Merge branch 'mesa_7_7_branch'

Conflicts:

	src/mesa/drivers/dri/i965/brw_wm_emit.c
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 b10d1fe..1b46a91 100644
--- a/Makefile
+++ b/Makefile
@@ -105,6 +105,7 @@
 irix6-o32 \
 irix6-o32-static \
 linux \
+linux-i965 \
 linux-alpha \
 linux-alpha-static \
 linux-cell \
@@ -182,7 +183,7 @@
 
 # Rules for making release tarballs
 
-VERSION=7.7.1-devel
+VERSION=7.7
 DIRECTORY = Mesa-$(VERSION)
 LIB_NAME = MesaLib-$(VERSION)
 DEMO_NAME = MesaDemos-$(VERSION)
@@ -225,6 +226,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				\
@@ -240,7 +246,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]		\
diff --git a/SConstruct b/SConstruct
index f43c10c..787ff6e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -32,10 +32,10 @@
 default_statetrackers = 'mesa'
 
 if common.default_platform in ('linux', 'freebsd', 'darwin'):
-	default_drivers = 'softpipe,failover,svga,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,svga,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', 'svga', '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', 'vmware', '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')))
 
@@ -160,8 +160,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 3bec160..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"
@@ -755,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}
@@ -843,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}
@@ -866,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*)
@@ -888,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
@@ -936,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..f63618e 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@
@@ -66,12 +68,11 @@
 GLU_DIRS = @GLU_DIRS@
 DRIVER_DIRS = @DRIVER_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:
diff --git a/configs/darwin b/configs/darwin
index 336b54e..7556688 100644
--- a/configs/darwin
+++ b/configs/darwin
@@ -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 gallium 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 c9616bb..94beca4 100644
--- a/configs/default
+++ b/configs/default
@@ -9,8 +9,8 @@
 
 # Version info
 MESA_MAJOR=7
-MESA_MINOR=7
-MESA_TINY=1
+MESA_MINOR=8
+MESA_TINY=0
 MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY)
 
 # external projects.  This should be useless now that we use libdrm.
@@ -83,7 +83,7 @@
 
 # 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:
@@ -94,9 +94,8 @@
 
 # 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 failover svga i915 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 =
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-dri b/configs/linux-dri
index 0802543..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 = vmware 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 a15ca11..d8af5ea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -95,7 +95,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"
@@ -414,13 +414,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=""
 
@@ -447,10 +446,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
@@ -578,13 +574,6 @@
     GL_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED dri2proto >= $DRI2PROTO_REQUIRED"
     DRI_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED"
 
-    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
-
     # find the DRI deps for libGL
     if test "$x11_pkgconfig" = yes; then
         # add xcb modules if necessary
@@ -804,6 +793,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
@@ -1221,10 +1233,10 @@
     [enable_gallium_intel="$enableval"],
     [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"
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965"
 fi
 
 dnl
@@ -1306,7 +1318,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/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/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 b06548a..f1f95c5 100644
--- a/docs/relnotes.html
+++ b/docs/relnotes.html
@@ -13,6 +13,8 @@
 </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>
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/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/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/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/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 f30b893..9c351e8 100644
--- a/progs/demos/fire.c
+++ b/progs/demos/fire.c
@@ -734,7 +734,6 @@
       HEIGHT = atoi(av[3]);
    }
 
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutInit(&ac, av);
 
diff --git a/progs/demos/fogcoord.c b/progs/demos/fogcoord.c
index 7d5c11a..336aa58 100644
--- a/progs/demos/fogcoord.c
+++ b/progs/demos/fogcoord.c
@@ -404,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 acba3e9..395b7ca 100644
--- a/progs/demos/fslight.c
+++ b/progs/demos/fslight.c
@@ -600,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 e6567dd..00b6e78 100644
--- a/progs/demos/geartrain.c
+++ b/progs/demos/geartrain.c
@@ -1060,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 ed03673..265378b 100644
--- a/progs/demos/ipers.c
+++ b/progs/demos/ipers.c
@@ -682,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 dd56965..dbe4d8d 100644
--- a/progs/demos/isosurf.c
+++ b/progs/demos/isosurf.c
@@ -1063,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 01a06ab..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 );
 
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 503cf5d..d162568 100644
--- a/progs/demos/projtex.c
+++ b/progs/demos/projtex.c
@@ -998,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 e9211aa..9cc464d 100644
--- a/progs/demos/ray.c
+++ b/progs/demos/ray.c
@@ -856,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 182b01d..cc4e490 100644
--- a/progs/demos/readpix.c
+++ b/progs/demos/readpix.c
@@ -383,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 9ba7b61..a72c8d3 100644
--- a/progs/demos/terrain.c
+++ b/progs/demos/terrain.c
@@ -626,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 31e1bbb..1415ef1 100644
--- a/progs/demos/textures.c
+++ b/progs/demos/textures.c
@@ -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/fp/SConscript b/progs/fp/SConscript
index 69614e1..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',
@@ -23,7 +12,7 @@
 ]
 
 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 26af66a..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);
 }
 
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/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/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 50a0900..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 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/deriv.c b/progs/glsl/deriv.c
index 30f2b75..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();
@@ -163,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 =
@@ -181,6 +189,7 @@
    program = LinkShaders(vertShader, fragShader);
 
    glUseProgram(program);
+   WinSizeUniform = glGetUniformLocation(program, "WinSize");
 
    /*assert(glGetError() == 0);*/
 
@@ -220,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/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/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/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/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/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/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/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/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/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/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/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/tri-orig.c b/progs/trivial/tri-orig.c
index d86d34c..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);
 }
 
@@ -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/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/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/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/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/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 f4e82e8..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 += [
@@ -370,7 +272,6 @@
             '-Wno-long-long',
             '-ffast-math',
             '-fmessage-length=0', # be nice to Eclipse
-            '-fno-strict-aliasing', # we violate strict pointer aliasing rules
         ]
         cflags += [
             '-Werror=declaration-after-statement',
@@ -535,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/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/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.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 4865a2d..2801dba 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -314,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 1ee2bf9..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.
@@ -246,6 +246,7 @@
    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;
@@ -274,7 +275,8 @@
       fenced_buffer_remove_locked(fenced_list, fenced_buf);
       pipe_mutex_unlock(fenced_buf->mutex);
 
-      pb_reference((struct pb_buffer **)&fenced_buf, NULL);
+      pb_buf = &fenced_buf->base;
+      pb_reference(&pb_buf, NULL);
 
       curr = next; 
       next = curr->next;
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/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/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/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 b7569e7..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:
-            assert( 0 );
-            return;
-         }
-
-         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 2c39def..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;
@@ -2253,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:
@@ -2514,7 +2518,7 @@
       break;
 
    case TGSI_OPCODE_TXL:
-      emit_tex( func, inst, TRUE, FALSE );
+      return 0;
       break;
 
    case TGSI_OPCODE_TXP:
@@ -2586,7 +2590,7 @@
       return 0;
       break;
 
-   case TGSI_OPCODE_SHR:
+   case TGSI_OPCODE_ISHR:
       return 0;
       break;
 
@@ -2642,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++ ) {
@@ -2961,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 bf39cf5..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];
@@ -279,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,
@@ -350,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:
@@ -417,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
@@ -452,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;
@@ -475,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;
@@ -502,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);
 }
 
 
@@ -541,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;
@@ -560,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;
@@ -661,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;
 }
 
@@ -705,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;
 }
 
@@ -734,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;
 }
 
 
@@ -749,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;
 }
 
 
@@ -918,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;
 
 }
 
@@ -944,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];
 }
 
 
@@ -975,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, 
@@ -985,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++) {
@@ -1023,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,
@@ -1032,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 );
    }
 }
 
@@ -1055,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_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..cef3b69
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -0,0 +1,726 @@
+/**************************************************************************
+ *
+ * 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;
+   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);
+}
+
+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;
+   struct pipe_framebuffer_state fb_state;
+   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;
+
+   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);
+   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);
+   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 6be5ca2..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 = 0;
+      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_debug.c b/src/gallium/auxiliary/util/u_debug.c
index be5eb87..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
@@ -602,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,
@@ -671,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_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_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%
rename from src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
rename 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 bd27f34..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;
 };
 
@@ -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_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h
index 9dacc6d..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,34 +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 = 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]);
@@ -318,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_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/drivers/dri/intel/intel_swapbuffers.h b/src/gallium/auxiliary/util/u_texture.h
similarity index 60%
copy from src/mesa/drivers/dri/intel/intel_swapbuffers.h
copy to src/gallium/auxiliary/util/u_texture.h
index 75bb624..93b2f1e 100644
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.h
+++ b/src/gallium/auxiliary/util/u_texture.h
@@ -1,9 +1,7 @@
-
 /**************************************************************************
- * 
- * Copyright 2006 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
@@ -11,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.
@@ -23,30 +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 INTEL_SWAPBUFFERS_H
-#define INTEL_SWAPBUFFERS_H
+#ifndef U_TEXTURE_H
+#define U_TEXTURE_H
 
-#include "dri_util.h"
-#include "drm.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-struct intel_context;
-struct intel_framebuffer;
+/**
+ * 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
-intelSwapBuffers(__DRIdrawablePrivate * dPriv);
+#ifdef __cplusplus
+}
+#endif
 
-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 */
+#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 bbe0d5f..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
@@ -363,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
@@ -417,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);
    }
 
@@ -474,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
@@ -567,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
@@ -626,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);
    }
 
@@ -648,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 */
@@ -689,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]);
@@ -843,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;
 
@@ -1294,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);
 
@@ -1307,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);
 
@@ -1321,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]);
 
@@ -1335,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]);
 
@@ -1349,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]);
 
@@ -1363,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]);
 
@@ -1378,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]);
 
@@ -1393,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]);
 
@@ -1461,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) {
@@ -1500,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) {
@@ -1644,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_context.c b/src/gallium/drivers/i915/i915_context.c
index 94c8aee..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);
 }
 
 
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_state.c b/src/gallium/drivers/i915/i915_state.c
index a04668d..5f5b6f8 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -74,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;
@@ -221,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;
    }
@@ -752,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;
@@ -791,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/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/drivers/dri/intel/intel_swapbuffers.h b/src/gallium/drivers/i965/brw_draw.h
similarity index 66%
copy from src/mesa/drivers/dri/intel/intel_swapbuffers.h
copy to src/gallium/drivers/i965/brw_draw.h
index 75bb624..8dc5dbc 100644
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.h
+++ b/src/gallium/drivers/i965/brw_draw.h
@@ -1,7 +1,6 @@
-
-/**************************************************************************
+ /**************************************************************************
  * 
- * Copyright 2006 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
@@ -26,27 +25,15 @@
  * 
  **************************************************************************/
 
-#ifndef INTEL_SWAPBUFFERS_H
-#define INTEL_SWAPBUFFERS_H
+#ifndef BRW_DRAW_H
+#define BRW_DRAW_H
 
-#include "dri_util.h"
-#include "drm.h"
+#include "brw_types.h"
 
-struct intel_context;
-struct intel_framebuffer;
+struct brw_context;
+
+boolean brw_draw_init( struct brw_context *brw );
+void brw_draw_cleanup( struct brw_context *brw );
 
 
-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 */
+#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..0c3f00f 100644
--- a/src/gallium/drivers/llvmpipe/README
+++ b/src/gallium/drivers/llvmpipe/README
@@ -51,21 +51,22 @@
 
  - 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
-     cd udis86
-     ./configure --with-pic
-     make
-     sudo make install
+   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.5. On Debian based distributions do:
+ - LLVM 2.5 or greater. LLVM 2.6 is preferred.
+ 
+   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:
+   There is a typo in one of the llvm 2.5 headers, that may cause compilation
+   errors. To fix it apply the change:
 
      --- /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
@@ -79,12 +80,17 @@
           #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
+ - 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
+ 
 
 Building
 ========
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_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_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_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 0dea2cd..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 = 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;
@@ -768,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;
@@ -1315,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/drivers/dri/intel/intel_swapbuffers.h b/src/gallium/drivers/llvmpipe/lp_debug.h
similarity index 62%
copy from src/mesa/drivers/dri/intel/intel_swapbuffers.h
copy to src/gallium/drivers/llvmpipe/lp_debug.h
index 75bb624..74b2757 100644
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.h
+++ b/src/gallium/drivers/llvmpipe/lp_debug.h
@@ -1,7 +1,6 @@
-
 /**************************************************************************
  * 
- * Copyright 2006 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,27 +25,47 @@
  * 
  **************************************************************************/
 
-#ifndef INTEL_SWAPBUFFERS_H
-#define INTEL_SWAPBUFFERS_H
 
-#include "dri_util.h"
-#include "drm.h"
+#ifndef LP_DEBUG_H
+#define LP_DEBUG_H
 
-struct intel_context;
-struct intel_framebuffer;
-
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
 
 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);
+st_print_current(void);
 
 
-#endif /* INTEL_SWAPBUFFERS_H */
+#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_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 b2e75d3..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)
@@ -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 8e2aae4..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;
 }
@@ -712,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);
@@ -723,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_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_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 699394c..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 = 0.0F;
-
-   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/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 65a22b1..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_TRANSLATE_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 7ba9777..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_VTXBUF_ADDRESS(i), 1);
-		OUT_RING(0/*nv10->vtxbuf*/);
-		BEGIN_RING(celsius, NV10TCL_VTXFMT(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 276db8b..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_TRANSLATE_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_SCALE_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 0ce702d..2d565cb 100644
--- a/src/gallium/drivers/nv30/nv30_fragprog.c
+++ b/src/gallium/drivers/nv30/nv30_fragprog.c
@@ -237,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;
@@ -258,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);
@@ -268,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;
 }
 
@@ -281,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);
 	}
 }
@@ -363,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);
 		}
 	}
@@ -372,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:
@@ -385,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);
@@ -400,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);
@@ -413,7 +413,7 @@
 			/* handled above */
 			break;
 		case TGSI_FILE_SAMPLER:
-			unit = fsrc->SrcRegister.Index;
+			unit = fsrc->Register.Index;
 			break;
 		case TGSI_FILE_OUTPUT:
 			break;
@@ -423,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) {
@@ -435,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;
@@ -517,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:
@@ -572,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");
@@ -591,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;
@@ -604,7 +620,7 @@
 		return FALSE;
 	}
 
-	fpc->attrib_map[fdec->DeclarationRange.First] = hw;
+	fpc->attrib_map[fdec->Range.First] = hw;
 	return TRUE;
 }
 
@@ -612,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");
@@ -653,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:
@@ -821,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 |
@@ -870,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 7cd3690..9ed4817 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -156,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);
@@ -163,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);
 }
@@ -224,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);
@@ -261,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..53f9f0a 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,10 +131,11 @@
 	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];
 	unsigned temp_temp_nr;
@@ -131,23 +144,30 @@
 	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 +196,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
@@ -229,6 +248,21 @@
 	assert(0);
 }
 
+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
  * contain loops), we need to assign all hw regs to TGSI TEMPs early,
  * lest we risk temp_temps overwriting regs alloc'd "later".
@@ -255,22 +289,6 @@
 	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)
@@ -342,25 +360,34 @@
 kill_temp_temp(struct nv50_pc *pc)
 {
 	int i;
-	
+
 	for (i = 0; i < pc->temp_temp_nr; i++)
 		free_temp(pc, pc->temp_temp[i]);
 	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 +395,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;
@@ -418,10 +445,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 +500,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 +540,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 +565,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 +584,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 +599,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 +657,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 +678,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 +693,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 +710,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)
@@ -795,6 +868,33 @@
 }
 
 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 +909,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 +971,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 +985,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 +1005,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 +1027,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 +1050,34 @@
 }
 
 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_mad(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
 	 struct nv50_reg *src1, struct nv50_reg *src2)
 {
@@ -967,12 +1103,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 +1123,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 +1153,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 +1173,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 +1240,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 +1260,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 +1277,108 @@
 	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 = alloc_temp(pc, NULL);
+		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);
+
+	if (src1 != rsrc1)
+		free_temp(pc, src1);
+}
+
+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;
+	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;
+}
+
 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 +1387,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 +1416,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);
+		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);
+		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 +1455,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 +1571,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 +1580,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 +1592,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 +1829,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 +1852,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 +1875,17 @@
 		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;
+		break;
 	case 0x8:
 		/* INTERP (move centroid, perspective and flat bits) */
 		m = ~0x03000100;
@@ -1506,50 +1922,62 @@
 }
 
 /* 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_UMAX:
+	case TGSI_OPCODE_UMIN:
+	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 +1992,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 +2050,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 +2076,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 +2093,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 +2135,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);
+		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 +2215,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 +2257,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,33 +2310,33 @@
 	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;
@@ -1901,7 +2361,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:
@@ -1924,24 +2385,36 @@
 	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);
+		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 +2422,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);
 		}
 		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 +2488,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 +2500,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);
+		t[1] = temp_temp(pc);
+
+		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++) {
@@ -2059,27 +2583,85 @@
 			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);
+		if (mask & (1 << 1))
+			t[1] = temp_temp(pc);
+		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);
@@ -2101,14 +2683,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:
@@ -2129,35 +2711,58 @@
 		emit_pow(pc, brdc, src[0][0], src[1][0]);
 		break;
 	case TGSI_OPCODE_RCP:
-		emit_flop(pc, 0, brdc, src[0][0]);
+		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]);
+		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);
 		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);
 		}
 		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 +2770,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,18 +2797,54 @@
 		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_XPD:
@@ -2213,6 +2865,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 +2902,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);
+	pc->reg_instance_nr = 0;
+
 	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 +2940,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 +2957,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 +3025,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 +3045,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 +3054,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 +3069,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,7 +3095,7 @@
 	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)) {
@@ -2438,7 +3106,7 @@
 	}
 	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 +3114,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 +3157,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 +3203,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 +3215,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 +3226,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 +3238,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 +3308,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 +3340,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 +3357,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 +3397,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 +3489,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 +3565,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 +3587,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 +3626,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 +3650,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 +3673,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 +3721,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 +3821,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 +3857,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 +3867,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]);
@@ -3236,15 +3884,15 @@
 	struct nv50_program *vp = nv50->vertprog;
 	unsigned i, c, m = base;
 
-	/* 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,10 +3900,16 @@
 			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];
 
@@ -3343,20 +3997,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 +4025,7 @@
 	}
 
 	/* now fill the stateobj */
-	so = so_new(64, 0);
+	so = so_new(6, 58, 0);
 
 	n = (m + 3) / 4;
 	so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1);
@@ -3381,7 +4039,7 @@
 	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) {
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 f605c47..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);
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index e1b2f11..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,33 +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);
 
 	/* activate all 32 lanes (threads) in a warp */
-	so_method(so, screen->tesla, 0x19a0, 1);
+	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);
@@ -354,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);
 	*/
 
@@ -387,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;
@@ -398,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;
@@ -411,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 799d275..f83232f 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -33,7 +33,7 @@
 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;
 
@@ -41,7 +41,7 @@
 	 * 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_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));
@@ -87,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);
 	}
 
@@ -124,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 */
@@ -156,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;
@@ -201,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);
@@ -245,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;
 
@@ -264,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]));
@@ -282,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);
 	}
@@ -299,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);
@@ -328,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]));
@@ -367,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);
 
@@ -405,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);
@@ -416,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 121b650..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 \
@@ -17,13 +17,13 @@
 	r300_state.c \
 	r300_state_derived.c \
 	r300_state_invariant.c \
-	r300_vbo.c \
 	r300_vs.c \
 	r300_texture.c \
 	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
 
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..ffe066d
--- /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);
+    util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state);
+    util_blitter_save_rasterizer(r300->blitter, r300->rs_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 ae23329..d5c2d63 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -28,7 +28,7 @@
 #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_flush.h"
 #include "r300_query.h"
@@ -36,6 +36,7 @@
 #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 +52,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);
@@ -69,6 +72,7 @@
     FREE(r300->blend_color_state);
     FREE(r300->rs_block);
     FREE(r300->scissor_state);
+    FREE(r300->vertex_info);
     FREE(r300->viewport_state);
     FREE(r300);
 }
@@ -104,7 +108,7 @@
 }
 
 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);
@@ -112,9 +116,9 @@
     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);
@@ -122,16 +126,27 @@
     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;
 
-    if (r300screen->caps->has_tcl)
-    {
+    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
-    {
-        assert(0);
+    } 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;
@@ -143,18 +158,9 @@
     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->vertex_info = CALLOC_STRUCT(r300_vertex_info);
     r300->viewport_state = CALLOC_STRUCT(r300_viewport_state);
 
-    /* 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);
-
     /* Open up the OQ BO. */
     r300->oqbo = screen->buffer_create(screen, 4096,
             PIPE_BUFFER_USAGE_VERTEX, 4096);
@@ -173,5 +179,8 @@
     r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300);
     r300->dirty_state = R300_NEW_KITCHEN_SINK;
     r300->dirty_hw++;
+
+    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 f954ba7..232530b 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -25,6 +25,8 @@
 
 #include "draw/draw_vertex.h"
 
+#include "util/u_blitter.h"
+
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
 
@@ -89,14 +91,28 @@
 };
 
 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 */
+
+    /* Whether everything is culled by scissoring. */
+    boolean empty_area;
 };
 
 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 {
@@ -219,11 +235,6 @@
 struct r300_vertex_info {
     /* Parent class */
     struct vertex_info vinfo;
-    /* 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];
 
     /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
     uint32_t vap_prog_stream_cntl[8];
@@ -238,9 +249,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;
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 5342488..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
@@ -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; \
-    int cs_count = 0
+    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 b44c7bd..f8bfa71 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,6 +23,7 @@
 
 /* r300_emit: Functions for emitting state. */
 
+#include "util/u_format.h"
 #include "util/u_math.h"
 
 #include "r300_context.h"
@@ -40,9 +42,16 @@
     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);
+    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_ROPCNTL, blend->rop);
     OUT_CS_REG(R300_RB3D_DITHER_CTL, blend->dither);
     END_CS;
@@ -112,8 +121,15 @@
     }*/
 
     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);
 
@@ -129,7 +145,9 @@
     struct rc_constant * constant,
     struct r300_constant_buffer * externals)
 {
-    static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 };
+    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 +155,60 @@
         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). */
+                case RC_STATE_SHADOW_AMBIENT:
+                    vec[3] = 0;
+                    break;
+
+                case RC_STATE_R300_VIEWPORT_SCALE:
+                    if (r300->rs_state->enable_vte) {
+                        vec[0] = r300->viewport_state->xscale;
+                        vec[1] = r300->viewport_state->yscale;
+                        vec[2] = r300->viewport_state->zscale;
+                    } else {
+                        vec[0] = 1;
+                        vec[1] = 1;
+                        vec[2] = 1;
+                    }
+                    break;
+
+                case RC_STATE_R300_VIEWPORT_OFFSET:
+                    if (r300->rs_state->enable_vte) {
+                        vec[0] = r300->viewport_state->xoffset;
+                        vec[1] = r300->viewport_state->yoffset;
+                        vec[2] = r300->viewport_state->zoffset;
+                    } else {
+                        /* Zeros. */
+                    }
+                    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);
@@ -543,24 +640,36 @@
     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,
+                             struct r300_scissor_state* scissor)
+{
+    if (r300->rs_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 */
@@ -569,13 +678,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);
@@ -584,50 +700,68 @@
     END_CS;
 }
 
-/* XXX I can't read this and that's not good */
-void r300_emit_aos(struct r300_context* r300, unsigned offset)
+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;
-    CS_LOCALS(r300);
     int i;
-    unsigned aos_count = r300->vertex_element_count;
 
+    /* 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) {
-        int buf_num1 = velem[i].vertex_buffer_index;
-        int buf_num2 = velem[i+1].vertex_buffer_index;
-        assert(vbuf[buf_num1].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
-        assert(vbuf[buf_num2].stride % 4 == 0 && pf_get_size(velem[i+1].src_format) % 4 == 0);
-        OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num1].stride << 6) |
-               (pf_get_size(velem[i+1].src_format) << 14) | (vbuf[buf_num2].stride << 22));
-        OUT_CS(vbuf[buf_num1].buffer_offset + velem[i].src_offset +
-               offset * vbuf[buf_num1].stride);
-        OUT_CS(vbuf[buf_num2].buffer_offset + velem[i+1].src_offset +
-               offset * vbuf[buf_num2].stride);
-    }
-    if (aos_count & 1) {
-        int buf_num = velem[i].vertex_buffer_index;
-        assert(vbuf[buf_num].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
-        OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num].stride << 6));
-        OUT_CS(vbuf[buf_num].buffer_offset + velem[i].src_offset +
-               offset * vbuf[buf_num].stride);
+        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);
     }
 
-    /* XXX bare CS reloc */
+    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++) {
-        cs_winsys->write_cs_reloc(cs_winsys,
-                                  vbuf[velem[i].vertex_buffer_index].buffer,
-                                  RADEON_GEM_DOMAIN_GTT,
-                                  0,
-                                  0);
-        cs_count -= 2;
+        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)
 {
@@ -690,12 +824,22 @@
     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) {
@@ -708,8 +852,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) |
@@ -722,10 +865,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;
 }
 
@@ -790,13 +934,33 @@
     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_flush_textures(struct r300_context* r300)
 {
     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;
 }
 
@@ -821,10 +985,17 @@
         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);
+    }
+
     /* 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++) {
@@ -910,19 +1081,22 @@
     }
 
     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;
     }
@@ -950,6 +1124,8 @@
     /* 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))) {
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 7c83c51..3797d3d 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -92,6 +92,8 @@
 void r300_emit_viewport_state(struct r300_context* r300,
                               struct r300_viewport_state* viewport);
 
+void r300_emit_texture_count(struct r300_context* r300);
+
 void r300_flush_textures(struct r300_context* r300);
 
 /* Emit all dirty state. */
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 744ea65..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)
@@ -2144,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)
@@ -2184,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)
@@ -3292,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 62e1456..a4ac9ad 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -37,7 +37,6 @@
 #include "r300_reg.h"
 #include "r300_render.h"
 #include "r300_state_derived.h"
-#include "r300_vbo.h"
 
 /* r300_render: Vertex and index buffer primitive emission. */
 #define R300_MAX_VBO_SIZE  (1024 * 1024)
@@ -70,14 +69,67 @@
     }
 }
 
+static boolean r300_nothing_to_draw(struct r300_context *r300)
+{
+    return r300->rs_state->rs.scissor &&
+           r300->scissor_state->scissor.empty_area;
+}
+
+static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
+                                            unsigned mode)
+{
+    uint32_t color_control = r300->rs_state->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 (r300->rs_state->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(4);
-    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count);
+    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));
@@ -102,7 +154,10 @@
     assert((start * indexSize)  % 4 == 0);
     assert(offset_dwords == 0);
 
-    BEGIN_CS(10);
+    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) {
@@ -158,7 +213,7 @@
 }
 
 /* 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,
@@ -170,22 +225,34 @@
     struct r300_context* r300 = r300_context(pipe);
 
     if (!u_trim_pipe_prim(mode, &count)) {
-        return FALSE;
+        return;
     }
 
     if (count > 65535) {
-        return FALSE;
+       /* XXX: use aux/indices functions to split this into smaller
+        * primitives.
+        */
+        return;
+    }
+
+    if (r300_nothing_to_draw(r300)) {
+        return;
     }
 
     r300_update_derived_state(r300);
 
     if (!r300_setup_vertex_buffers(r300)) {
-        return FALSE;
+        return;
     }
 
-    setup_vertex_attributes(r300);
+    if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
+                                  RADEON_GEM_DOMAIN_GTT, 0)) {
+        return;
+    }
 
-    setup_index_buffer(r300, indexBuffer, indexSize);
+    if (!r300->winsys->validate(r300->winsys)) {
+        return;
+    }
 
     r300_emit_dirty_state(r300);
 
@@ -193,48 +260,49 @@
 
     r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex,
                             mode, start, count);
-
-    return TRUE;
 }
 
 /* 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)
 {
     struct r300_context* r300 = r300_context(pipe);
 
     if (!u_trim_pipe_prim(mode, &count)) {
-        return FALSE;
+        return;
     }
 
     if (count > 65535) {
-        return FALSE;
+        /* XXX: driver needs to handle this -- use the functions in
+         * aux/indices to split this into several smaller primitives.
+         */
+        return;
+    }
+
+    if (r300_nothing_to_draw(r300)) {
+        return;
     }
 
     r300_update_derived_state(r300);
 
     if (!r300_setup_vertex_buffers(r300)) {
-        return FALSE;
+        return;
     }
 
-    setup_vertex_attributes(r300);
-
     r300_emit_dirty_state(r300);
 
     r300_emit_aos(r300, start);
 
     r300_emit_draw_arrays(r300, mode, count);
-
-    return TRUE;
 }
 
 /****************************************************************************
@@ -243,7 +311,7 @@
  ***************************************************************************/
 
 /* SW TCL arrays, using Draw. */
-boolean r300_swtcl_draw_arrays(struct pipe_context* pipe,
+void r300_swtcl_draw_arrays(struct pipe_context* pipe,
                                unsigned mode,
                                unsigned start,
                                unsigned count)
@@ -252,7 +320,11 @@
     int i;
 
     if (!u_trim_pipe_prim(mode, &count)) {
-        return FALSE;
+        return;
+    }
+
+    if (r300_nothing_to_draw(r300)) {
+        return;
     }
 
     for (i = 0; i < r300->vertex_buffer_count; i++) {
@@ -265,8 +337,9 @@
     draw_set_mapped_element_buffer(r300->draw, 0, NULL);
 
     draw_set_mapped_constant_buffer(r300->draw,
-            r300->shader_constants[PIPE_SHADER_VERTEX].constants,
-            r300->shader_constants[PIPE_SHADER_VERTEX].count *
+				    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);
@@ -275,12 +348,10 @@
         pipe_buffer_unmap(pipe->screen, r300->vertex_buffer[i].buffer);
         draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
     }
-
-    return TRUE;
 }
 
 /* SW TCL elements, using Draw. */
-boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
+void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
                                        struct pipe_buffer* indexBuffer,
                                        unsigned indexSize,
                                        unsigned minIndex,
@@ -291,9 +362,14 @@
 {
     struct r300_context* r300 = r300_context(pipe);
     int i;
+    void* indices;
 
     if (!u_trim_pipe_prim(mode, &count)) {
-        return FALSE;
+        return;
+    }
+
+    if (r300_nothing_to_draw(r300)) {
+        return;
     }
 
     for (i = 0; i < r300->vertex_buffer_count; i++) {
@@ -303,12 +379,13 @@
         draw_set_mapped_vertex_buffer(r300->draw, i, buf);
     }
 
-    void* indices = pipe_buffer_map(pipe->screen, indexBuffer,
-                                    PIPE_BUFFER_USAGE_CPU_READ);
+    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));
@@ -323,8 +400,6 @@
     pipe_buffer_unmap(pipe->screen, indexBuffer);
     draw_set_mapped_element_buffer_range(r300->draw, 0, start,
                                          start + count - 1, NULL);
-
-    return TRUE;
 }
 
 /* Object for rendering using Draw. */
@@ -400,7 +475,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 da83069..27b5e6a 100644
--- a/src/gallium/drivers/r300/r300_render.h
+++ b/src/gallium/drivers/r300/r300_render.h
@@ -25,35 +25,35 @@
 
 uint32_t r300_translate_primitive(unsigned prim);
 
-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);
+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_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);
 
-boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
-                         unsigned start, unsigned count);
+void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
+                      unsigned start, unsigned count);
 
-boolean r300_swtcl_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);
 
-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_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 d1eced6..a145a7f 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) {
@@ -151,9 +340,10 @@
                                  const struct pipe_blend_color* color)
 {
     struct r300_context* r300 = r300_context(pipe);
+    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);
+    r300->blend_color_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 =
@@ -282,11 +472,29 @@
     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);
+    }
+
+    scissor->empty_area = state->minx >= state->maxx ||
+                          state->miny >= state->maxy;
 }
 
 static void
@@ -294,6 +502,7 @@
                                const struct pipe_framebuffer_state* state)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct pipe_scissor_state scissor;
 
     if (r300->draw) {
         draw_flush(r300->draw);
@@ -301,7 +510,19 @@
 
     r300->framebuffer_state = *state;
 
+    scissor.minx = scissor.miny = 0;
+    scissor.maxx = state->width;
+    scissor.maxy = state->height;
+    r300_set_scissor_regs(&scissor, &r300->scissor_state->framebuffer,
+                          r300_screen(r300->context.screen)->caps->is_r500);
+
+    /* Don't rely on the order of states being set for the first time. */
+    if (!r300->rs_state || !r300->rs_state->rs.scissor) {
+        r300->dirty_state |= R300_NEW_SCISSOR;
+    }
     r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
+    r300->dirty_state |= R300_NEW_BLEND;
+    r300->dirty_state |= R300_NEW_DSA;
 }
 
 /* Create fragment shader state. */
@@ -317,6 +538,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 +552,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 +568,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);
 }
@@ -382,8 +614,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 +704,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;
 }
 
@@ -498,6 +724,9 @@
     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 +742,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 +753,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 +767,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 +797,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,6 +823,7 @@
                                       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 */
@@ -578,13 +831,18 @@
         return;
     }
     
-    r300->context.flush(&r300->context, 0, NULL);
-
     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;
+            }
         }
     }
 
@@ -604,24 +862,13 @@
 {
     struct r300_context* r300 = r300_context(pipe);
 
-    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, &r300->scissor_state->scissor,
+                          r300_screen(r300->context.screen)->caps->is_r500);
 
-    r300->dirty_state |= R300_NEW_SCISSOR;
+    /* Don't rely on the order of states being set for the first time. */
+    if (!r300->rs_state || r300->rs_state->rs.scissor) {
+        r300->dirty_state |= R300_NEW_SCISSOR;
+    }
 }
 
 static void r300_set_viewport_state(struct pipe_context* pipe,
@@ -658,6 +905,9 @@
     }
 
     r300->dirty_state |= R300_NEW_VIEWPORT;
+    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,
@@ -674,6 +924,8 @@
         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,
@@ -706,9 +958,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);
@@ -719,8 +968,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;
 
@@ -731,10 +978,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);
     }
@@ -748,7 +1001,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 {
@@ -798,8 +1050,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;
@@ -813,10 +1063,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 7166694..22660a5 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,209 +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_info* 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;
-    } else {
-        /* Use fragment shader to determine required routes. */
-        info = &r300->fs->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);
+}
 
-    assert(info->num_inputs <= 16);
-
-    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;
-            }
-        }
-    }
-    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 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;
-    }
+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 (r300->draw) {
-        draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
-            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
+    if (vs_outputs->pos != ATTR_UNUSED) {
+        r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+                              vs_outputs->pos);
+    } else {
+        assert(0);
     }
-    vinfo->hwfmt[1] |= R300_INPUT_CNTL_POS;
-    vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
 
     /* Point size. */
-    if (psize) {
-        if (r300->draw) {
-            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;
+    if (vs_outputs->psize != ATTR_UNUSED) {
+        r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS,
+                              vs_outputs->psize);
     }
 
     /* Colors. */
-    for (i = 0; i < cols; i++) {
-        if (r300->draw) {
-            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR,
-                draw_find_vs_output(r300->draw, TGSI_SEMANTIC_COLOR, i));
+    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]);
         }
-        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;
+    /* XXX Back-face colors. */
 
-    /* Fog. This is a special-cased texcoord. */
-    if (fog) {
-        i++;
-        if (r300->draw) {
-            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
-                draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0));
+    /* 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++;
         }
-        vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
-        vinfo->hwfmt[3] |= (4 << (3 * i));
     }
 
-    /* Texcoords. */
-    for (; i < texs; i++) {
-        if (r300->draw) {
-            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));
+    /* Fog coordinates. */
+    if (vs_outputs->fog != ATTR_UNUSED) {
+        r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+                              vs_outputs->fog);
+        gen_count++;
     }
 
-    draw_compute_vertex_size(vinfo);
+    /* XXX magic */
+    assert(gen_count <= 8);
 }
 
 /* Update the PSC tables. */
-static void r300_vertex_psc(struct r300_context* r300,
-                            struct r300_vertex_info* 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->rs_state->enable_vte) {
+        stream_tab = identity;
+    } else {
+        stream_tab = r300->vs->stream_loc_notcl;
+    }
+
+    /* 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! */
@@ -272,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;
         }
     }
 
@@ -289,185 +232,212 @@
         (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_info* 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_screen* r300screen = r300_screen(r300->context.screen);
-    struct r300_vertex_info* vformat;
-    struct r300_rs_block* rs_block;
-    int i;
 
     /*
     struct r300_shader_key* key;
@@ -495,27 +465,45 @@
             (void*)key, (void*)value);
     } */
 
-    /* XXX This will be refactored ASAP. */
-    vformat = CALLOC_STRUCT(r300_vertex_info);
-    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)
@@ -534,28 +522,34 @@
      * 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
      *
      * ~C.
      */
-    if (r300->dsa_state->alpha_function) {
+
+    /* ZS writes */
+    if (r300_dsa_writes_depth_stencil(r300->dsa_state) &&
+           (r300_dsa_alpha_test_enabled(r300->dsa_state) ||   /* (1) */
+            r300->fs->info.uses_kill)) {                      /* (2) */
         r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
-    } else if (r300->fs->info.uses_kill) {
+    } else if (r300_fragment_shader_writes_depth(r300->fs)) { /* (5) */
         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) {
+    } else if (r300->query_current) {                         /* (6) */
         r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
     }
 }
 
 void r300_update_derived_state(struct r300_context* r300)
 {
-    /* XXX */
-    if (TRUE || r300->dirty_state &
-        (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER)) {
+    if (r300->dirty_state &
+        (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER |
+         R300_NEW_VERTEX_FORMAT)) {
         r300_update_derived_shader_state(r300);
     }
 
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index e6c1cb5..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. */
@@ -255,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:
@@ -443,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++;
     }
 
@@ -467,19 +470,23 @@
 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) {
+    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:
@@ -488,19 +495,15 @@
                     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 {
@@ -510,8 +513,8 @@
                 default:
                     debug_printf("r300: Bad format %s in %s:%d\n",
                         pf_name(format), __FUNCTION__, __LINE__);
-                    debug_printf("r300: pf_size_x(format) == %d\n",
-                        pf_size_x(format));
+                    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;
@@ -521,12 +524,11 @@
             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;
@@ -534,17 +536,21 @@
 
 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) {
+    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));
 }
 
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_vbo.c b/src/gallium/drivers/r300/r300_vbo.c
deleted file mode 100644
index a6a1596..0000000
--- a/src/gallium/drivers/r300/r300_vbo.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2009 Maciej Cencora <m.cencora@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.
- */
-
-/* r300_vbo: Various helpers for emitting vertex buffers. Needs cleanup,
- * refactoring, etc. */
-
-#include "r300_vbo.h"
-
-#include "pipe/p_format.h"
-
-#include "r300_cs.h"
-#include "r300_context.h"
-#include "r300_state_inlines.h"
-#include "r300_reg.h"
-#include "r300_winsys.h"
-
-static INLINE void setup_vertex_attribute(struct r300_vertex_info *vinfo,
-                                          struct pipe_vertex_element *vert_elem,
-                                          unsigned attr_num)
-{
-    uint16_t hw_fmt1, hw_fmt2;
-
-    hw_fmt1 = r300_translate_vertex_data_type(vert_elem->src_format) |
-        (attr_num << R300_DST_VEC_LOC_SHIFT);
-    hw_fmt2 = r300_translate_vertex_data_swizzle(vert_elem->src_format);
-
-    if (attr_num % 2 == 0)
-    {
-        vinfo->vap_prog_stream_cntl[attr_num >> 1] = hw_fmt1;
-        vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] = hw_fmt2;
-    }
-    else
-    {
-        vinfo->vap_prog_stream_cntl[attr_num >> 1] |= hw_fmt1 << 16;
-        vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] |= hw_fmt2 << 16;
-    }
-}
-
-static void finish_vertex_attribs_setup(struct r300_vertex_info *vinfo,
-                                        unsigned attribs_num)
-{
-    uint32_t last_vec_bit = (attribs_num % 2 == 0) ?
-        (R300_LAST_VEC << 16) : R300_LAST_VEC;
-
-    assert(attribs_num > 0 && attribs_num <= 16);
-    vinfo->vap_prog_stream_cntl[(attribs_num - 1) >> 1] |= last_vec_bit;
-}
-
-void setup_vertex_attributes(struct r300_context *r300)
-{
-    struct pipe_vertex_element *vert_elem;
-    int i;
-
-    for (i = 0; i < r300->vertex_element_count; i++) {
-        vert_elem = &r300->vertex_element[i];
-        setup_vertex_attribute(r300->vertex_info, vert_elem, i);
-    }
-
-    finish_vertex_attribs_setup(r300->vertex_info,
-        r300->vertex_element_count);
-}
-
-static INLINE int get_buffer_offset(struct r300_context *r300,
-                                    unsigned int buf_nr,
-                                    unsigned int elem_offset)
-{
-    return r300->vertex_buffer[buf_nr].buffer_offset + elem_offset;
-}
-#if 0
-/* XXX not called at all */
-static void setup_vertex_buffers(struct r300_context *r300)
-{
-    struct pipe_vertex_element *vert_elem;
-    int i;
-
-    for (i = 0; i < r300->aos_count; i++)
-    {
-        vert_elem = &r300->vertex_element[i];
-            /* XXX use translate module to convert the data */
-        if (!format_is_supported(vert_elem->src_format,
-                                 vert_elem->nr_components)) {
-            assert(0);
-            /*
-            struct pipe_buffer *buf;
-            const unsigned int max_index = r300->vertex_buffers[vert_elem->vertex_buffer_index].max_index;
-            buf = pipe_buffer_create(r300->context.screen, 4, usage, vert_elem->nr_components * max_index * sizeof(float));
-            */
-        }
-
-        if (get_buffer_offset(r300,
-                              vert_elem->vertex_buffer_index,
-                              vert_elem->src_offset) % 4) {
-            /* XXX need to align buffer */
-            assert(0);
-        }
-    }
-}
-#endif
-/* XXX these shouldn't be asserts since we can work around bad indexbufs */
-void setup_index_buffer(struct r300_context *r300,
-                        struct pipe_buffer* indexBuffer,
-                        unsigned indexSize)
-{
-    if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
-                                  RADEON_GEM_DOMAIN_GTT, 0)) {
-        assert(0);
-    }
-
-    if (!r300->winsys->validate(r300->winsys)) {
-        assert(0);
-    }
-}
diff --git a/src/gallium/drivers/r300/r300_vbo.h b/src/gallium/drivers/r300/r300_vbo.h
deleted file mode 100644
index 7afa758..0000000
--- a/src/gallium/drivers/r300/r300_vbo.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2009 Maciej Cencora <m.cencora@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_VBO_H
-#define R300_VBO_H
-
-struct r300_context;
-struct pipe_buffer;
-
-void setup_vertex_attributes(struct r300_context *r300);
-
-void setup_index_buffer(struct r300_context *r300,
-                        struct pipe_buffer* indexBuffer,
-                        unsigned indexSize);
-
-#endif
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 5f60139..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);
@@ -152,6 +158,11 @@
           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;
 }
@@ -165,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 )
 {
@@ -180,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;
@@ -191,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;
@@ -210,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;
@@ -225,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;
@@ -236,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!
@@ -246,7 +277,9 @@
 
    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);
@@ -262,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);
 
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_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 b41f7e8..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;
 }
@@ -159,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/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 32e9304..66259fd 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -203,8 +203,6 @@
    struct pipe_clip_state clip;
    struct pipe_viewport_state viewport;
 
-   const unsigned *edgeflags;
-
    unsigned num_samplers;
    unsigned num_textures;
    unsigned num_vertex_elements;
@@ -370,7 +368,7 @@
 #define SVGA_NEW_FRAME_BUFFER        0x800
 #define SVGA_NEW_STIPPLE             0x1000
 #define SVGA_NEW_SCISSOR             0x2000
-#define SVGA_NEW_BLEND_COLOR         0x5000
+#define SVGA_NEW_BLEND_COLOR         0x4000
 #define SVGA_NEW_CLIP                0x8000
 #define SVGA_NEW_VIEWPORT            0x10000
 #define SVGA_NEW_PRESCALE            0x20000
@@ -381,9 +379,8 @@
 #define SVGA_NEW_NEED_SWTNL          0x400000
 #define SVGA_NEW_FS_RESULT           0x800000
 #define SVGA_NEW_VS_RESULT           0x1000000
-#define SVGA_NEW_EDGEFLAGS           0x2000000
-#define SVGA_NEW_ZERO_STRIDE         0x4000000
-#define SVGA_NEW_TEXTURE_FLAGS       0x8000000
+#define SVGA_NEW_ZERO_STRIDE         0x2000000
+#define SVGA_NEW_TEXTURE_FLAGS       0x4000000
 
 
 
diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c
index 6195c38..409b3b4 100644
--- a/src/gallium/drivers/svga/svga_pipe_clear.c
+++ b/src/gallium/drivers/svga/svga_pipe_clear.c
@@ -46,7 +46,7 @@
    boolean restore_viewport = FALSE;
    SVGA3dClearFlag flags = 0;
    struct pipe_framebuffer_state *fb = &svga->curr.framebuffer;
-   unsigned color = 0;
+   union util_color uc;
 
    ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR);
    if (ret)
@@ -54,7 +54,7 @@
 
    if ((buffers & PIPE_CLEAR_COLOR) && fb->cbufs[0]) {
       flags |= SVGA3D_CLEAR_COLOR;
-      util_pack_color(rgba, PIPE_FORMAT_A8R8G8B8_UNORM, &color);
+      util_pack_color(rgba, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
 
       rect.w = fb->cbufs[0]->width;
       rect.h = fb->cbufs[0]->height;
@@ -77,7 +77,7 @@
          return ret;
    }
 
-   ret = SVGA3D_ClearRect(svga->swc, flags, color, depth, stencil,
+   ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui, depth, stencil,
                           rect.x, rect.y, rect.w, rect.h);
    if (ret != PIPE_OK)
       return ret;
diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c
index 71a5528..0f24ef4 100644
--- a/src/gallium/drivers/svga/svga_pipe_draw.c
+++ b/src/gallium/drivers/svga/svga_pipe_draw.c
@@ -149,7 +149,7 @@
 
 
 
-static boolean
+static void
 svga_draw_range_elements( struct pipe_context *pipe,
                           struct pipe_buffer *index_buffer,
                           unsigned index_size,
@@ -162,7 +162,7 @@
    enum pipe_error ret = 0;
 
    if (!u_trim_pipe_prim( prim, &count ))
-      return TRUE;
+      return;
 
    /*
     * Mark currently bound target surfaces as dirty
@@ -183,7 +183,7 @@
 #ifdef DEBUG
    if (svga->curr.vs->base.id == svga->debug.disable_shader ||
        svga->curr.fs->base.id == svga->debug.disable_shader)
-      return 0;
+      return;
 #endif
 
    if (svga->state.sw.need_swtnl)
@@ -225,31 +225,29 @@
       svga_hwtnl_flush_retry( svga );
       svga_context_flush(svga, NULL);
    }
-
-   return ret == PIPE_OK;
 }
 
 
-static boolean 
+static void
 svga_draw_elements( struct pipe_context *pipe,
                     struct pipe_buffer *index_buffer,
                     unsigned index_size,
                     unsigned prim, unsigned start, unsigned count)
 {
-   return svga_draw_range_elements( pipe, index_buffer,
-                                    index_size,
-                                    0, 0xffffffff,
-                                    prim, start, count );
+   svga_draw_range_elements( pipe, index_buffer,
+                             index_size,
+                             0, 0xffffffff,
+                             prim, start, count );
 }
 
-static boolean 
+static void
 svga_draw_arrays( struct pipe_context *pipe,
                   unsigned prim, unsigned start, unsigned count)
 {
-   return svga_draw_range_elements(pipe, NULL, 0, 
-                                   start, start + count - 1, 
-                                   prim, 
-                                   start, count);
+   svga_draw_range_elements(pipe, NULL, 0, 
+                            start, start + count - 1, 
+                            prim, 
+                            start, count);
 }
 
 
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c
index 3eeca6b..460a101 100644
--- a/src/gallium/drivers/svga/svga_pipe_sampler.c
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -76,7 +76,6 @@
    switch (filter) {
    case PIPE_TEX_FILTER_NEAREST: return SVGA3D_TEX_FILTER_NEAREST;
    case PIPE_TEX_FILTER_LINEAR:  return SVGA3D_TEX_FILTER_LINEAR;
-   case PIPE_TEX_FILTER_ANISO:   return SVGA3D_TEX_FILTER_ANISOTROPIC;
    default:
       assert(0);
       return SVGA3D_TEX_FILTER_NEAREST;
@@ -101,11 +100,14 @@
 {
    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);
@@ -121,8 +123,8 @@
       ubyte a = float_to_ubyte(sampler->border_color[3]);
 
       util_pack_color_ub( r, g, b, a,
-                          PIPE_FORMAT_B8G8R8A8_UNORM,
-                          &cso->bordercolor );
+                          PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
+      cso->bordercolor = uc.ui;
    }
 
    /* No SVGA3D support for:
@@ -234,9 +236,9 @@
 void svga_init_sampler_functions( struct svga_context *svga )
 {
    svga->pipe.create_sampler_state = svga_create_sampler_state;
-   svga->pipe.bind_sampler_states = svga_bind_sampler_states;
+   svga->pipe.bind_fragment_sampler_states = svga_bind_sampler_states;
    svga->pipe.delete_sampler_state = svga_delete_sampler_state;
-   svga->pipe.set_sampler_textures = svga_set_sampler_textures;
+   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
index 28e2787..42f290d 100644
--- a/src/gallium/drivers/svga/svga_pipe_vertex.c
+++ b/src/gallium/drivers/svga/svga_pipe_vertex.c
@@ -84,18 +84,6 @@
 }
 
 
-static void svga_set_edgeflags(struct pipe_context *pipe,
-                               const unsigned *bitfield)
-{
-   struct svga_context *svga = svga_context(pipe);
-
-   if (bitfield != NULL || svga->curr.edgeflags != NULL) {
-      svga->curr.edgeflags = bitfield;
-      svga->dirty |= SVGA_NEW_EDGEFLAGS;
-   }
-}
-
-
 void svga_cleanup_vertex_state( struct svga_context *svga )
 {
    unsigned i;
@@ -109,7 +97,6 @@
 {
    svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
    svga->pipe.set_vertex_elements = svga_set_vertex_elements;
-   svga->pipe.set_edgeflags = svga_set_edgeflags;
 }
 
 
diff --git a/src/gallium/drivers/svga/svga_pipe_vs.c b/src/gallium/drivers/svga/svga_pipe_vs.c
index fd9864c..7e6ab57 100644
--- a/src/gallium/drivers/svga/svga_pipe_vs.c
+++ b/src/gallium/drivers/svga/svga_pipe_vs.c
@@ -49,7 +49,7 @@
    static struct tgsi_token tokens[300];
 
    const char *text = 
-      "VERT1.1\n"
+      "VERT\n"
       "DCL IN[0]\n"
       "DCL IN[1]\n"
       "DCL IN[2]\n"
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_screen_buffer.c
index 1f8a889..58a1aba 100644
--- a/src/gallium/drivers/svga/svga_screen_buffer.c
+++ b/src/gallium/drivers/svga/svga_screen_buffer.c
@@ -356,7 +356,8 @@
    sbuf->hw.boxes = NULL;
 
    /* Decrement reference count */
-   pipe_buffer_reference((struct pipe_buffer **)&sbuf, NULL);
+   pipe_reference(&(sbuf->base.reference), NULL);
+   sbuf = NULL;
 }
 
 
diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
index 1eb03db..2224c2d 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ b/src/gallium/drivers/svga/svga_screen_texture.c
@@ -29,6 +29,7 @@
 #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"
 
@@ -158,7 +159,8 @@
                 st->base.x + st->base.width,
                 y + h,
                 st->base.zslice + 1,
-                texture->base.block.size*8/(texture->base.block.width*texture->base.block.height));
+                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;
@@ -208,7 +210,8 @@
    }
    else {
       unsigned y, h, srcy;
-      h = st->hw_nblocksy * st->base.block.height;
+      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;
@@ -218,11 +221,11 @@
             h = st->base.height - y;
 
          /* Transfer band must be aligned to pixel block boundaries */
-         assert(y % st->base.block.height == 0);
-         assert(h % st->base.block.height == 0);
+         assert(y % blockheight == 0);
+         assert(h % blockheight == 0);
          
-         offset = y * st->base.stride / st->base.block.height;
-         length = h * st->base.stride / st->base.block.height;
+         offset = y * st->base.stride / blockheight;
+         length = h * st->base.stride / blockheight;
 
          sw = (uint8_t *)st->swbuf + offset;
          
@@ -281,24 +284,19 @@
    if(templat->last_level >= SVGA_MAX_TEXTURE_LEVELS)
       goto error2;
    
-   width = templat->width[0];
-   height = templat->height[0];
-   depth = templat->depth[0];
+   width = templat->width0;
+   height = templat->height0;
+   depth = templat->depth0;
    for(level = 0; level <= templat->last_level; ++level) {
-      tex->base.width[level] = width;
-      tex->base.height[level] = height;
-      tex->base.depth[level] = depth;
-      tex->base.nblocksx[level] = pf_get_nblocksx(&tex->base.block, width);  
-      tex->base.nblocksy[level] = pf_get_nblocksy(&tex->base.block, height);  
-      width  = minify(width);
-      height = minify(height);
-      depth = minify(depth);
+      width = u_minify(width, 1);
+      height = u_minify(height, 1);
+      depth = u_minify(depth, 1);
    }
    
    tex->key.flags = 0;
-   tex->key.size.width = templat->width[0];
-   tex->key.size.height = templat->height[0];
-   tex->key.size.depth = templat->depth[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;
@@ -322,7 +320,7 @@
     */
 #if 0
    if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) &&
-      !pf_is_compressed(templat->format))
+      !util_format_is_compressed(templat->format))
       tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
 #endif
    
@@ -365,7 +363,7 @@
    /* Only supports one type */
    if (base->target != PIPE_TEXTURE_2D ||
        base->last_level != 0 ||
-       base->depth[0] != 1) {
+       base->depth0 != 1) {
       return NULL;
    }
 
@@ -538,9 +536,9 @@
    key->flags = 0;
    key->format = format;
    key->numMipLevels = num_mip;
-   key->size.width = tex->base.width[start_mip];
-   key->size.height = tex->base.height[start_mip];
-   key->size.depth = zslice_pick < 0 ? tex->base.depth[start_mip] : 1;
+   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);
    
@@ -574,7 +572,10 @@
    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 ? tex->base.depth[i + start_mip] : 1;
+            unsigned depth = (zslice_pick < 0 ?
+                              u_minify(tex->base.depth0, i + start_mip) :
+                              1);
+
             svga_texture_copy_handle(svga_context(pipe),
                                      ss,
                                      tex->handle, 
@@ -582,8 +583,8 @@
                                      i + start_mip, 
                                      j + face_pick,
                                      handle, 0, 0, 0, i, j,
-                                     tex->base.width[i + start_mip],
-                                     tex->base.height[i + start_mip],
+                                     u_minify(tex->base.width0, i + start_mip),
+                                     u_minify(tex->base.height0, i + start_mip),
                                      depth);
          }
       }
@@ -612,8 +613,8 @@
    pipe_reference_init(&s->base.reference, 1);
    pipe_texture_reference(&s->base.texture, pt);
    s->base.format = pt->format;
-   s->base.width = pt->width[level];
-   s->base.height = pt->height[level];
+   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;
@@ -742,7 +743,8 @@
       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,
-                               tex->base.width[surf->level], tex->base.height[surf->level], 1);
+                               u_minify(tex->base.width0, surf->level),
+                               u_minify(tex->base.height0, surf->level), 1);
       tex->defined[surf->face][surf->level] = TRUE;
    }
 }
@@ -770,6 +772,8 @@
    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)
@@ -779,21 +783,17 @@
    if (!st)
       return NULL;
    
-   st->base.format = texture->format;
-   st->base.block = texture->block;
    st->base.x = x;
    st->base.y = y;
    st->base.width = w;
    st->base.height = h;
-   st->base.nblocksx = pf_get_nblocksx(&texture->block, w);
-   st->base.nblocksy = pf_get_nblocksy(&texture->block, h);
-   st->base.stride = st->base.nblocksx*st->base.block.size;
+   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 = st->base.nblocksy;
+   st->hw_nblocksy = nblocksy;
    
    st->hwbuf = svga_winsys_buffer_create(ss, 
                                          1, 
@@ -809,15 +809,15 @@
    if(!st->hwbuf)
       goto no_hwbuf;
 
-   if(st->hw_nblocksy < st->base.nblocksy) {
+   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__,
-                   (st->base.nblocksy*st->base.stride + 1023)/1024,
-                   (st->base.nblocksy + st->hw_nblocksy - 1)/st->hw_nblocksy,
+                   (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(st->base.nblocksy*st->base.stride);
+      st->swbuf = MALLOC(nblocksy*st->base.stride);
       if(!st->swbuf)
          goto no_swbuf;
    }
@@ -932,7 +932,7 @@
       if (min_lod == 0 && max_lod >= pt->last_level)
          view = FALSE;
 
-      if (pf_is_compressed(pt->format) && view) {
+      if (util_format_is_compressed(pt->format) && view) {
          format = svga_translate_format_render(pt->format);
       }
 
@@ -971,9 +971,9 @@
                "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->width[0],
-               pt->height[0],
-               pt->depth[0],
+               pt->width0,
+               pt->height0,
+               pt->depth0,
                pt->last_level);
       sv->key.cachable = 0;
       sv->handle = tex->handle;
@@ -984,9 +984,9 @@
             "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->width[0],
-            pt->height[0],
-            pt->depth[0],
+            pt->width0,
+            pt->height0,
+            pt->depth0,
             pt->last_level);
 
    sv->age = tex->age;
@@ -1036,9 +1036,9 @@
             svga_texture_copy_handle(svga, NULL,
                                      tex->handle, 0, 0, 0, i, k,
                                      v->handle, 0, 0, 0, i - v->min_lod, k,
-                                     tex->base.width[i],
-                                     tex->base.height[i],
-                                     tex->base.depth[i]);
+                                     u_minify(tex->base.width0, i),
+                                     u_minify(tex->base.height0, i),
+                                     u_minify(tex->base.depth0, i));
       }
    }
 
@@ -1071,8 +1071,7 @@
        svga_translate_format(texture->format),
        stex->handle);
 
-   *stride = pf_get_nblocksx(&texture->block, texture->width[0]) *
-      texture->block.size;
+   *stride = util_format_get_stride(texture->format, texture->width0);
 
    return *buffer != NULL;
 }
diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h
index 8cfdfea..89ae242 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.h
+++ b/src/gallium/drivers/svga/svga_screen_texture.h
@@ -171,8 +171,9 @@
 {
    struct svga_sampler_view *old = *ptr;
 
-   if (pipe_reference((struct pipe_reference **)ptr, &v->reference))
+   if (pipe_reference(&(*ptr)->reference, &v->reference))
       svga_destroy_sampler_view_priv(old);
+   *ptr = v;
 }
 
 extern void
diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c
index a5777d4..6b0e511 100644
--- a/src/gallium/drivers/svga/svga_state_constants.c
+++ b/src/gallium/drivers/svga/svga_state_constants.c
@@ -140,8 +140,8 @@
             struct pipe_texture *tex = svga->curr.texture[i];
             float data[4];
 
-            data[0] = 1.0 / (float)tex->width[0];
-            data[1] = 1.0 / (float)tex->height[0];
+            data[0] = 1.0 / (float)tex->width0;
+            data[1] = 1.0 / (float)tex->height0;
             data[2] = 1.0;
             data[3] = 1.0;
 
diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c
index 44bb58c..d29f376 100644
--- a/src/gallium/drivers/svga/svga_state_fs.c
+++ b/src/gallium/drivers/svga/svga_state_fs.c
@@ -40,8 +40,13 @@
 static INLINE int compare_fs_keys( const struct svga_fs_compile_key *a,
                                    const struct svga_fs_compile_key *b )
 {
-   unsigned keysize = svga_fs_key_size( a );
-   return memcmp( a, b, keysize );
+   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 );
 }
 
 
diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c
index 00201b8..3c35a85 100644
--- a/src/gallium/drivers/svga/svga_state_need_swtnl.c
+++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c
@@ -108,6 +108,7 @@
 {
    
    boolean need_pipeline = FALSE;
+   struct svga_vertex_shader *vs = svga->curr.vs;
 
    /* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
     */
@@ -119,11 +120,9 @@
       need_pipeline = TRUE;
    }
 
-   /* SVGA_NEW_EDGEFLAGS
+   /* EDGEFLAGS
     */
-   if (svga->curr.rast->hw_unfilled != PIPE_POLYGON_MODE_FILL &&
-       svga->curr.reduced_prim == PIPE_PRIM_TRIANGLES && 
-       svga->curr.edgeflags != NULL) {
+    if (vs->base.info.writes_edgeflag) {
       SVGA_DBG(DEBUG_SWTNL, "%s: edgeflags\n", __FUNCTION__);
       need_pipeline = TRUE;
    }
@@ -150,6 +149,7 @@
    "need pipeline",
    (SVGA_NEW_RAST |
     SVGA_NEW_CLIP |
+    SVGA_NEW_VS |
     SVGA_NEW_REDUCED_PRIMITIVE),
    update_need_pipeline
 };
diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c
index db30f27..ae1e77e 100644
--- a/src/gallium/drivers/svga/svga_state_vs.c
+++ b/src/gallium/drivers/svga/svga_state_vs.c
@@ -25,6 +25,7 @@
 
 #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"
@@ -216,7 +217,7 @@
          mapped_buffer = pipe_buffer_map_range(svga->pipe.screen, 
                                                vbuffer->buffer,
                                                vel->src_offset,
-                                               pf_get_size(vel->src_format),
+                                               util_format_get_blocksize(vel->src_format),
                                                PIPE_BUFFER_USAGE_CPU_READ);
          translate->set_buffer(translate, vel->vertex_buffer_index,
                                mapped_buffer,
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index 8b14c91..7655121 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -90,7 +90,7 @@
                             PIPE_BUFFER_USAGE_CPU_READ);
       assert(map);
       draw_set_mapped_constant_buffer(
-         draw, 
+         draw, PIPE_SHADER_VERTEX,
          map,
          svga->curr.cb[PIPE_SHADER_VERTEX]->size);
    }
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index 1616312..94b6ccc 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -120,10 +120,6 @@
       draw_set_mrd(svga->swtnl.draw, 
                    svga->curr.depthscale);
 
-   if (dirty & SVGA_NEW_EDGEFLAGS)
-      draw_set_edgeflags( svga->swtnl.draw, 
-                          svga->curr.edgeflags );
-
    return 0;
 }
 
@@ -138,8 +134,7 @@
     SVGA_NEW_VIEWPORT |
     SVGA_NEW_RAST |
     SVGA_NEW_FRAME_BUFFER |
-    SVGA_NEW_REDUCED_PRIMITIVE |
-    SVGA_NEW_EDGEFLAGS),
+    SVGA_NEW_REDUCED_PRIMITIVE),
    update_swtnl_draw
 };
 
@@ -161,7 +156,7 @@
    memset(vdecl, 0, sizeof(vdecl));
 
    /* always add position */
-   src = draw_find_vs_output(draw, TGSI_SEMANTIC_POSITION, 0);
+   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;
@@ -174,7 +169,7 @@
    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_vs_output(draw, name, index);
+      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];
 
diff --git a/src/gallium/drivers/svga/svga_tgsi.h b/src/gallium/drivers/svga/svga_tgsi.h
index 896c90a..737a221 100644
--- a/src/gallium/drivers/svga/svga_tgsi.h
+++ b/src/gallium/drivers/svga/svga_tgsi.h
@@ -39,26 +39,24 @@
 
 struct svga_vs_compile_key
 {
-   ubyte need_prescale:1;
-   ubyte allow_psiz:1;
    unsigned zero_stride_vertex_elements;
-   ubyte num_zero_stride_vertex_elements:6;
+   unsigned need_prescale:1;
+   unsigned allow_psiz:1;
+   unsigned num_zero_stride_vertex_elements:6;
 };
 
 struct svga_fs_compile_key
 {
-   boolean light_twoside:1;
-   boolean front_cw:1;
-   ubyte num_textures;
-   ubyte num_unnormalized_coords;
+   unsigned light_twoside:1;
+   unsigned front_cw:1;
+   unsigned num_textures:8;
+   unsigned num_unnormalized_coords:8;
    struct {
-      ubyte compare_mode       : 1;
-      ubyte compare_func       : 3;
-      ubyte unnormalized       : 1;
-
-      ubyte width_height_idx   : 7;
-
-      ubyte texture_target;
+      unsigned compare_mode:1;
+      unsigned compare_func:3;
+      unsigned unnormalized:1;
+      unsigned width_height_idx:7;
+      unsigned texture_target:8;
    } tex[PIPE_MAX_SAMPLERS];
 };
 
@@ -121,8 +119,7 @@
 
 static INLINE unsigned svga_fs_key_size( const struct svga_fs_compile_key *key )
 {
-   return (const char *)&key->tex[key->num_textures].texture_target -
-      (const char *)key;
+   return (const char *)&key->tex[key->num_textures] - (const char *)key;
 }
 
 struct svga_shader_result *
diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
index 5445708..23b3ace 100644
--- a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
+++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
@@ -46,7 +46,7 @@
    dcl.values[0] = 0;
    dcl.values[1] = 0;
 
-   switch (semantic.SemanticName) {
+   switch (semantic.Name) {
    case TGSI_SEMANTIC_POSITION:
       /* Special case:
        */
@@ -55,15 +55,15 @@
       break;
    case TGSI_SEMANTIC_COLOR:
       reg = src_register( SVGA3DREG_INPUT, 
-                          semantic.SemanticIndex );
+                          semantic.Index );
       break;
    case TGSI_SEMANTIC_FOG:
-      assert(semantic.SemanticIndex == 0);
+      assert(semantic.Index == 0);
       reg = src_register( SVGA3DREG_TEXTURE, 0 );
       break;
    case TGSI_SEMANTIC_GENERIC:
       reg = src_register( SVGA3DREG_TEXTURE,
-                          semantic.SemanticIndex + 1 );
+                          semantic.Index + 1 );
       break;
    default:
       assert(0);
@@ -90,16 +90,16 @@
 {
    SVGA3dShaderDestToken reg;
 
-   switch (semantic.SemanticName) {
+   switch (semantic.Name) {
    case TGSI_SEMANTIC_COLOR:
-      if (semantic.SemanticIndex < PIPE_MAX_COLOR_BUFS) {
-         unsigned cbuf = semantic.SemanticIndex;
+      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.SemanticIndex );
+                                              semantic.Index );
       }
       else {
          assert(0);
@@ -111,7 +111,7 @@
                                             emit->nr_hw_temp++ );
       emit->temp_pos = emit->output_map[idx];
       emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT, 
-                                     semantic.SemanticIndex );
+                                     semantic.Index );
       break;
    default:
       assert(0);
@@ -169,9 +169,9 @@
 
    /* Just build the register map table: 
     */
-   switch (semantic.SemanticName) {
+   switch (semantic.Name) {
    case TGSI_SEMANTIC_POSITION:
-      assert(semantic.SemanticIndex == 0);
+      assert(semantic.Index == 0);
       emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
                                             emit->nr_hw_temp++ );
       emit->temp_pos = emit->output_map[idx];
@@ -179,7 +179,7 @@
                                      SVGA3DRASTOUT_POSITION);
       break;
    case TGSI_SEMANTIC_PSIZE:
-      assert(semantic.SemanticIndex == 0);
+      assert(semantic.Index == 0);
       emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
                                             emit->nr_hw_temp++ );
       emit->temp_psiz = emit->output_map[idx];
@@ -187,17 +187,17 @@
                                       SVGA3DRASTOUT_PSIZE );
       break;
    case TGSI_SEMANTIC_FOG:
-      assert(semantic.SemanticIndex == 0);
+      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.SemanticIndex );
+                                            semantic.Index );
       break;
    case TGSI_SEMANTIC_GENERIC:
       emit->output_map[idx] = dst_register( SVGA3DREG_TEXCRDOUT,
-                                            semantic.SemanticIndex + 1 );
+                                            semantic.Index + 1 );
       break;
    default:
       assert(0);
@@ -230,15 +230,15 @@
 boolean svga_translate_decl_sm20( struct svga_shader_emitter *emit,
                              const struct tgsi_full_declaration *decl )
 {
-   unsigned first = decl->DeclarationRange.First;
-   unsigned last = decl->DeclarationRange.Last;
+   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.SemanticName;
-      semantic_idx = decl->Semantic.SemanticIndex;
+      semantic = decl->Semantic.Name;
+      semantic_idx = decl->Semantic.Index;
    }
 
    for( idx = first; idx <= last; idx++ ) {
diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
index 08e7dfb..d1c7336 100644
--- a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
+++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
@@ -35,35 +35,35 @@
                                          unsigned *usage,
                                          unsigned *idx )
 {
-   switch (semantic.SemanticName) {
+   switch (semantic.Name) {
    case TGSI_SEMANTIC_POSITION:  
-      *idx = semantic.SemanticIndex;
+      *idx = semantic.Index;
       *usage = SVGA3D_DECLUSAGE_POSITION;
       break;
    case TGSI_SEMANTIC_COLOR:     
 
-      *idx = semantic.SemanticIndex;
+      *idx = semantic.Index;
       *usage = SVGA3D_DECLUSAGE_COLOR;
       break;
    case TGSI_SEMANTIC_BCOLOR:
-      *idx = semantic.SemanticIndex + 2; /* sharing with COLOR */
+      *idx = semantic.Index + 2; /* sharing with COLOR */
       *usage = SVGA3D_DECLUSAGE_COLOR;
       break;
    case TGSI_SEMANTIC_FOG:       
       *idx = 0;
-      assert(semantic.SemanticIndex == 0);
+      assert(semantic.Index == 0);
       *usage = SVGA3D_DECLUSAGE_TEXCOORD;
       break;
    case TGSI_SEMANTIC_PSIZE:     
-      *idx = semantic.SemanticIndex;
+      *idx = semantic.Index;
       *usage = SVGA3D_DECLUSAGE_PSIZE;
       break;
    case TGSI_SEMANTIC_GENERIC:   
-      *idx = semantic.SemanticIndex + 1; /* texcoord[0] is reserved for fog */
+      *idx = semantic.Index + 1; /* texcoord[0] is reserved for fog */
       *usage = SVGA3D_DECLUSAGE_TEXCOORD;
       break;
    case TGSI_SEMANTIC_NORMAL:    
-      *idx = semantic.SemanticIndex;
+      *idx = semantic.Index;
       *usage = SVGA3D_DECLUSAGE_NORMAL;
       break;
    default:
@@ -120,7 +120,7 @@
    unsigned usage, index;
    SVGA3dShaderDestToken reg;
 
-   if (semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
+   if (semantic.Name == TGSI_SEMANTIC_POSITION) {
       emit->input_map[idx] = src_register( SVGA3DREG_MISCTYPE,
                                            SVGA3DMISCREG_POSITION );
 
@@ -135,7 +135,7 @@
       return emit_decl( emit, reg, 0, 0 );
    }
    else if (emit->key.fkey.light_twoside &&
-            (semantic.SemanticName == TGSI_SEMANTIC_COLOR)) {
+            (semantic.Name == TGSI_SEMANTIC_COLOR)) {
 
       if (!translate_vs_ps_semantic( semantic, &usage, &index ))
          return FALSE;
@@ -150,7 +150,7 @@
       if (!emit_decl( emit, reg, usage, index ))
          return FALSE;
 
-      semantic.SemanticName = TGSI_SEMANTIC_BCOLOR;
+      semantic.Name = TGSI_SEMANTIC_BCOLOR;
       if (!translate_vs_ps_semantic( semantic, &usage, &index ))
          return FALSE;
 
@@ -164,7 +164,7 @@
 
       return TRUE;
    }
-   else if (semantic.SemanticName == TGSI_SEMANTIC_FACE) {
+   else if (semantic.Name == TGSI_SEMANTIC_FACE) {
       if (!emit_vface_decl( emit ))
          return FALSE;
       emit->emit_frontface = TRUE;
@@ -193,17 +193,17 @@
 {
    SVGA3dShaderDestToken reg;
 
-   switch (semantic.SemanticName) {
+   switch (semantic.Name) {
    case TGSI_SEMANTIC_COLOR:
       emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, 
-                                            semantic.SemanticIndex );
+                                            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.SemanticIndex );
+                                     semantic.Index );
       break;
    default:
       assert(0);
@@ -283,14 +283,14 @@
    dcl.index = index;
    dcl.values[0] |= 1<<31;
 
-   if (semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
+   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.SemanticName == TGSI_SEMANTIC_PSIZE) {
+   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];
@@ -335,15 +335,15 @@
 boolean svga_translate_decl_sm30( struct svga_shader_emitter *emit,
                              const struct tgsi_full_declaration *decl )
 {
-   unsigned first = decl->DeclarationRange.First;
-   unsigned last = decl->DeclarationRange.Last;
+   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.SemanticName;
-      semantic_idx = decl->Semantic.SemanticIndex;
+      semantic = decl->Semantic.Name;
+      semantic_idx = decl->Semantic.Index;
    }
 
    for( idx = first; idx <= last; idx++ ) {
diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c
index ea409b7..dc5eb8f 100644
--- a/src/gallium/drivers/svga/svga_tgsi_insn.c
+++ b/src/gallium/drivers/svga/svga_tgsi_insn.c
@@ -96,24 +96,24 @@
                         const struct tgsi_full_instruction *insn,
                         unsigned idx )
 {
-   const struct tgsi_full_dst_register *reg = &insn->FullDstRegisters[idx];
+   const struct tgsi_full_dst_register *reg = &insn->Dst[idx];
    SVGA3dShaderDestToken dest;
 
-   switch (reg->DstRegister.File) {
+   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->DstRegister.Index];
+      dest = emit->output_map[reg->Register.Index];
       break;
 
    default:
-      dest = dst_register( translate_file( reg->DstRegister.File ),
-                           reg->DstRegister.Index );
+      dest = dst_register( translate_file( reg->Register.File ),
+                           reg->Register.Index );
       break;
    }
 
-   dest.mask = reg->DstRegister.WriteMask;
+   dest.mask = reg->Register.WriteMask;
 
    if (insn->Instruction.Saturate) 
       dest.dstMod = SVGA3DDSTMOD_SATURATE;
@@ -176,33 +176,33 @@
 {
    struct src_register src;
 
-   switch (reg->SrcRegister.File) {
+   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->SrcRegister.Index];
+      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->SrcRegister.File ),
-                          reg->SrcRegister.Index + 
+      src = src_register( translate_file( reg->Register.File ),
+                          reg->Register.Index + 
                           emit->imm_start );
       break;
 
    default:
-      src = src_register( translate_file( reg->SrcRegister.File ),
-                          reg->SrcRegister.Index );
+      src = src_register( translate_file( reg->Register.File ),
+                          reg->Register.Index );
 
       break;
    }
 
    /* Indirect addressing (for coninstant buffer lookups only)
     */
-   if (reg->SrcRegister.Indirect)
+   if (reg->Register.Indirect)
    {
       /* we shift the offset towards the minimum */
       if (svga_arl_needs_adjustment( emit )) {
@@ -213,28 +213,28 @@
       /* Not really sure what should go in the second token:
        */
       src.indirect = src_token( SVGA3DREG_ADDR,
-                                reg->SrcRegisterInd.Index );
+                                reg->Indirect.Index );
 
       src.indirect.swizzle = SWIZZLE_XXXX;
    }
 
    src = swizzle( src,
-                  reg->SrcRegister.SwizzleX,
-                  reg->SrcRegister.SwizzleY,
-                  reg->SrcRegister.SwizzleZ,
-                  reg->SrcRegister.SwizzleW );
+                  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->SrcRegisterExtMod.Absolute) {
-      if (reg->SrcRegisterExtMod.Negate)
+   if (reg->Register.Absolute) {
+      if (reg->Register.Negate)
          src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
       else
          src.base.srcMod = SVGA3DSRCMOD_ABS;
    }
    else {
-      if (reg->SrcRegister.Negate != reg->SrcRegisterExtMod.Negate)
+      if (reg->Register.Negate)
          src.base.srcMod = SVGA3DSRCMOD_NEG;
       else
          src.base.srcMod = SVGA3DSRCMOD_NONE;
@@ -629,7 +629,7 @@
                              const struct tgsi_full_instruction *insn)
 {
    const struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      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 );
@@ -653,7 +653,7 @@
                        const struct tgsi_full_instruction *insn)
 {
    const struct src_register src = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    struct src_register zero = get_zero_immediate( emit );
    SVGA3dShaderInstToken if_token = inst_token( SVGA3DOP_IFC );
 
@@ -690,7 +690,7 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    const struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    SVGA3dShaderDestToken temp = get_temp( emit );
 
    /* FRC  TMP, SRC */
@@ -716,11 +716,11 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    const struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    const struct src_register src1 = translate_src_register(
-      emit, &insn->FullSrcRegisters[1] );
+      emit, &insn->Src[1] );
    const struct src_register src2 = translate_src_register(
-      emit, &insn->FullSrcRegisters[2] );
+      emit, &insn->Src[2] );
 
    /* CMP  DST, SRC0, SRC2, SRC1 */
    return submit_op3( emit, inst_token( SVGA3DOP_CMP ), dst, src0, src2, src1);
@@ -740,9 +740,9 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    const struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    const struct src_register src1 = translate_src_register(
-      emit, &insn->FullSrcRegisters[1] );
+      emit, &insn->Src[1] );
    SVGA3dShaderDestToken temp = get_temp( emit );
    int i;
 
@@ -782,9 +782,9 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    const struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    const struct src_register src1 = translate_src_register(
-      emit, &insn->FullSrcRegisters[1] );
+      emit, &insn->Src[1] );
    SVGA3dShaderDestToken temp = get_temp( emit );
    struct src_register temp_src0, temp_src1;
 
@@ -815,9 +815,9 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    const struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    struct src_register src1 = translate_src_register(
-      emit, &insn->FullSrcRegisters[1] );
+      emit, &insn->Src[1] );
    SVGA3dShaderDestToken temp = get_temp( emit );
 
    /* DP3  TMP, SRC1, SRC2 */
@@ -846,7 +846,7 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    const struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    SVGA3dShaderDestToken temp = get_temp( emit );
 
    /* DP3  TMP, SRC, SRC */
@@ -889,7 +889,7 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    SVGA3dShaderDestToken temp = get_temp( emit );
 
    /* SCS TMP SRC */
@@ -912,7 +912,7 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    SVGA3dShaderDestToken temp = get_temp( emit );
 
    /* SCS TMP SRC */
@@ -937,7 +937,7 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    SVGA3dShaderDestToken temp = get_temp( emit );
 
    /* SCS TMP SRC */
@@ -962,9 +962,9 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    struct src_register src1 = translate_src_register(
-      emit, &insn->FullSrcRegisters[1] );
+      emit, &insn->Src[1] );
 
    src1 = negate(src1);
 
@@ -980,19 +980,19 @@
                         const struct tgsi_full_instruction *insn )
 {
    SVGA3dShaderInstToken inst;
-   const struct tgsi_full_src_register *reg = &insn->FullSrcRegisters[0];
+   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->SrcRegisterExtMod.Absolute ||
-       reg->SrcRegister.Negate != reg->SrcRegisterExtMod.Negate ||
-       reg->SrcRegister.Indirect ||
-       reg->SrcRegister.SwizzleX != 0 ||
-       reg->SrcRegister.SwizzleY != 1 ||
-       reg->SrcRegister.SwizzleZ != 2 ||
-       reg->SrcRegister.File != TGSI_FILE_TEMPORARY)
+   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 );
 
@@ -1154,9 +1154,9 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    struct src_register src1 = translate_src_register(
-      emit, &insn->FullSrcRegisters[1] );
+      emit, &insn->Src[1] );
       
    return emit_select( emit, compare, dst, src0, src1 );
 }
@@ -1189,8 +1189,8 @@
       return FALSE;
    }
 
-   src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
-   src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
+   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 );
@@ -1231,9 +1231,9 @@
       break;
    }
 
-   src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
-   src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
-   src2 = translate_src_register( emit, &insn->FullSrcRegisters[2] );
+   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 );
 }
@@ -1245,9 +1245,9 @@
    SVGA3dShaderDestToken dst = 
       translate_dst_register( emit, insn, 0 );
    struct src_register src0 =
-      translate_src_register( emit, &insn->FullSrcRegisters[0] );
+      translate_src_register( emit, &insn->Src[0] );
    struct src_register src1 =
-      translate_src_register( emit, &insn->FullSrcRegisters[1] );
+      translate_src_register( emit, &insn->Src[1] );
 
    SVGA3dShaderDestToken tex_result;
 
@@ -1359,7 +1359,7 @@
 
    inst = inst_token( opcode );
    dst = translate_dst_register( emit, insn, 0 );
-   src = translate_src_register( emit, &insn->FullSrcRegisters[0] );
+   src = translate_src_register( emit, &insn->Src[0] );
    src = scalar( src, TGSI_SWIZZLE_X );
 
    return submit_op1( emit, inst, dst, src );
@@ -1370,7 +1370,7 @@
                                        unsigned opcode,
                                        const struct tgsi_full_instruction *insn )
 {
-   const struct tgsi_full_src_register *src = insn->FullSrcRegisters;
+   const struct tgsi_full_src_register *src = insn->Src;
    SVGA3dShaderInstToken inst;
    SVGA3dShaderDestToken dst;
 
@@ -1428,13 +1428,13 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    struct src_register src1 = translate_src_register(
-      emit, &insn->FullSrcRegisters[1] );
+      emit, &insn->Src[1] );
    boolean need_tmp = FALSE;
    
    /* POW can only output to a temporary */
-   if (insn->FullDstRegisters[0].DstRegister.File != TGSI_FILE_TEMPORARY)
+   if (insn->Dst[0].Register.File != TGSI_FILE_TEMPORARY)
       need_tmp = TRUE;
    
    /* POW src1 must not be the same register as dst */
@@ -1463,9 +1463,9 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    const struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    const struct src_register src1 = translate_src_register(
-      emit, &insn->FullSrcRegisters[1] );
+      emit, &insn->Src[1] );
    boolean need_dst_tmp = FALSE;
 
    /* XPD can only output to a temporary */
@@ -1517,11 +1517,11 @@
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    SVGA3dShaderDestToken tmp;
    const struct src_register src0 = translate_src_register(
-      emit, &insn->FullSrcRegisters[0] );
+      emit, &insn->Src[0] );
    const struct src_register src1 = translate_src_register(
-      emit, &insn->FullSrcRegisters[1] );
+      emit, &insn->Src[1] );
    const struct src_register src2 = translate_src_register(
-      emit, &insn->FullSrcRegisters[2] );
+      emit, &insn->Src[2] );
    boolean need_dst_tmp = FALSE;
 
    /* The dst reg must not be the same as src0 or src2 */
@@ -1568,9 +1568,9 @@
       SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
       SVGA3dShaderDestToken tmp;
       const struct src_register src0 = translate_src_register(
-         emit, &insn->FullSrcRegisters[0] );
+         emit, &insn->Src[0] );
       const struct src_register src1 = translate_src_register(
-         emit, &insn->FullSrcRegisters[1] );
+         emit, &insn->Src[1] );
       struct src_register zero = get_zero_immediate( emit );
       boolean need_tmp = FALSE;
 
@@ -1633,7 +1633,7 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    struct src_register src0 =
-      translate_src_register( emit, &insn->FullSrcRegisters[0] );
+      translate_src_register( emit, &insn->Src[0] );
    struct src_register zero = get_zero_immediate( emit );
    SVGA3dShaderDestToken fraction;
 
@@ -1723,7 +1723,7 @@
       SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
       SVGA3dShaderDestToken tmp = get_temp( emit );
       const struct src_register src0 = translate_src_register(
-         emit, &insn->FullSrcRegisters[0] );
+         emit, &insn->Src[0] );
       struct src_register zero = get_zero_immediate( emit );
 
       /* tmp = pow(src.y, src.w)
@@ -1806,7 +1806,7 @@
 
    inst = inst_token( SVGA3DOP_EXP );
    dst = translate_dst_register( emit, insn, 0 );
-   src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
+   src0 = translate_src_register( emit, &insn->Src[0] );
    src0 = scalar( src0, TGSI_SWIZZLE_X );
 
    if (dst.mask != TGSI_WRITEMASK_XYZW) {
@@ -1829,7 +1829,7 @@
 {
    SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
    struct src_register src0 =
-      translate_src_register( emit, &insn->FullSrcRegisters[0] );
+      translate_src_register( emit, &insn->Src[0] );
    struct src_register zero = get_zero_immediate( emit );
    SVGA3dShaderDestToken abs_tmp;
    struct src_register abs_src0;
@@ -1953,7 +1953,7 @@
 static boolean emit_call( struct svga_shader_emitter *emit,
                            const struct tgsi_full_instruction *insn )
 {
-   unsigned position = insn->InstructionExtLabel.Label;
+   unsigned position = insn->Label.Label;
    unsigned i;
    
    for (i = 0; i < emit->nr_labels; i++) {
@@ -2109,7 +2109,7 @@
    case TGSI_OPCODE_I2F:
    case TGSI_OPCODE_NOT:
    case TGSI_OPCODE_SHL:
-   case TGSI_OPCODE_SHR:
+   case TGSI_OPCODE_ISHR:
    case TGSI_OPCODE_XOR:
       return FALSE;
 
@@ -2543,27 +2543,27 @@
                        const struct tgsi_full_instruction *insn,
                        int current_arl)
 {
-   if (insn->FullSrcRegisters[0].SrcRegister.Indirect &&
-       insn->FullSrcRegisters[0].SrcRegisterInd.File == TGSI_FILE_ADDRESS) {
-      const struct tgsi_full_src_register *reg = &insn->FullSrcRegisters[0];
-      if (reg->SrcRegister.Index < 0) {
-         pre_parse_add_indirect(emit, reg->SrcRegister.Index, 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->FullSrcRegisters[1].SrcRegister.Indirect &&
-       insn->FullSrcRegisters[1].SrcRegisterInd.File == TGSI_FILE_ADDRESS) {
-      const struct tgsi_full_src_register *reg = &insn->FullSrcRegisters[1];
-      if (reg->SrcRegister.Index < 0) {
-         pre_parse_add_indirect(emit, reg->SrcRegister.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->FullSrcRegisters[2].SrcRegister.Indirect &&
-       insn->FullSrcRegisters[2].SrcRegisterInd.File == TGSI_FILE_ADDRESS) {
-      const struct tgsi_full_src_register *reg = &insn->FullSrcRegisters[2];
-      if (reg->SrcRegister.Index < 0) {
-         pre_parse_add_indirect(emit, reg->SrcRegister.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);
       }
    }
 
diff --git a/src/gallium/drivers/svga/svgadump/svga_dump.c b/src/gallium/drivers/svga/svgadump/svga_dump.c
index 910afa2..d59fb89 100644
--- a/src/gallium/drivers/svga/svgadump/svga_dump.c
+++ b/src/gallium/drivers/svga/svgadump/svga_dump.c
@@ -42,554 +42,554 @@
 {
    switch((*cmd).identity.type) {
    case SVGA3D_DECLTYPE_FLOAT1:
-      debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_FLOAT1\n");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.identity.type = %i\n", (*cmd).identity.type);
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _debug_printf("\t\t.identity.method = SVGA3D_DECLMETHOD_LOOKUPPRESAMPLED\n");
       break;
    default:
-      debug_printf("\t\t.identity.method = %i\n", (*cmd).identity.method);
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.identity.usage = %i\n", (*cmd).identity.usage);
+      _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);
+   _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);
+   _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");
+      _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");
+      _debug_printf("\t\t.name = SVGA3D_TS_BIND_TEXTURE\n");
       break;
    case SVGA3D_TS_COLOROP:
-      debug_printf("\t\t.name = SVGA3D_TS_COLOROP\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_COLOROP\n");
       break;
    case SVGA3D_TS_COLORARG1:
-      debug_printf("\t\t.name = SVGA3D_TS_COLORARG1\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_COLORARG1\n");
       break;
    case SVGA3D_TS_COLORARG2:
-      debug_printf("\t\t.name = SVGA3D_TS_COLORARG2\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_COLORARG2\n");
       break;
    case SVGA3D_TS_ALPHAOP:
-      debug_printf("\t\t.name = SVGA3D_TS_ALPHAOP\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_ALPHAOP\n");
       break;
    case SVGA3D_TS_ALPHAARG1:
-      debug_printf("\t\t.name = SVGA3D_TS_ALPHAARG1\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_ALPHAARG1\n");
       break;
    case SVGA3D_TS_ALPHAARG2:
-      debug_printf("\t\t.name = SVGA3D_TS_ALPHAARG2\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_ALPHAARG2\n");
       break;
    case SVGA3D_TS_ADDRESSU:
-      debug_printf("\t\t.name = SVGA3D_TS_ADDRESSU\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_ADDRESSU\n");
       break;
    case SVGA3D_TS_ADDRESSV:
-      debug_printf("\t\t.name = SVGA3D_TS_ADDRESSV\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_ADDRESSV\n");
       break;
    case SVGA3D_TS_MIPFILTER:
-      debug_printf("\t\t.name = SVGA3D_TS_MIPFILTER\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_MIPFILTER\n");
       break;
    case SVGA3D_TS_MAGFILTER:
-      debug_printf("\t\t.name = SVGA3D_TS_MAGFILTER\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_MAGFILTER\n");
       break;
    case SVGA3D_TS_MINFILTER:
-      debug_printf("\t\t.name = SVGA3D_TS_MINFILTER\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_MINFILTER\n");
       break;
    case SVGA3D_TS_BORDERCOLOR:
-      debug_printf("\t\t.name = SVGA3D_TS_BORDERCOLOR\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_BORDERCOLOR\n");
       break;
    case SVGA3D_TS_TEXCOORDINDEX:
-      debug_printf("\t\t.name = SVGA3D_TS_TEXCOORDINDEX\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_TEXCOORDINDEX\n");
       break;
    case SVGA3D_TS_TEXTURETRANSFORMFLAGS:
-      debug_printf("\t\t.name = SVGA3D_TS_TEXTURETRANSFORMFLAGS\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_TEXTURETRANSFORMFLAGS\n");
       break;
    case SVGA3D_TS_TEXCOORDGEN:
-      debug_printf("\t\t.name = SVGA3D_TS_TEXCOORDGEN\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_TEXCOORDGEN\n");
       break;
    case SVGA3D_TS_BUMPENVMAT00:
-      debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT00\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT00\n");
       break;
    case SVGA3D_TS_BUMPENVMAT01:
-      debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT01\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT01\n");
       break;
    case SVGA3D_TS_BUMPENVMAT10:
-      debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT10\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT10\n");
       break;
    case SVGA3D_TS_BUMPENVMAT11:
-      debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT11\n");
+      _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");
+      _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");
+      _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");
+      _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");
+      _debug_printf("\t\t.name = SVGA3D_TS_ADDRESSW\n");
       break;
    case SVGA3D_TS_GAMMA:
-      debug_printf("\t\t.name = SVGA3D_TS_GAMMA\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_GAMMA\n");
       break;
    case SVGA3D_TS_BUMPENVLSCALE:
-      debug_printf("\t\t.name = SVGA3D_TS_BUMPENVLSCALE\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVLSCALE\n");
       break;
    case SVGA3D_TS_BUMPENVLOFFSET:
-      debug_printf("\t\t.name = SVGA3D_TS_BUMPENVLOFFSET\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVLOFFSET\n");
       break;
    case SVGA3D_TS_COLORARG0:
-      debug_printf("\t\t.name = SVGA3D_TS_COLORARG0\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_COLORARG0\n");
       break;
    case SVGA3D_TS_ALPHAARG0:
-      debug_printf("\t\t.name = SVGA3D_TS_ALPHAARG0\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_ALPHAARG0\n");
       break;
    case SVGA3D_TS_MAX:
-      debug_printf("\t\t.name = SVGA3D_TS_MAX\n");
+      _debug_printf("\t\t.name = SVGA3D_TS_MAX\n");
       break;
    default:
-      debug_printf("\t\t.name = %i\n", (*cmd).name);
+      _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);
+   _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);
+   _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]);
+   _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);
+   _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");
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_OCCLUSION\n");
       break;
    case SVGA3D_QUERYTYPE_MAX:
-      debug_printf("\t\t.type = SVGA3D_QUERYTYPE_MAX\n");
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.type = %i\n", (*cmd).type);
+      _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);
+   _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);
+   _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");
+      _debug_printf("\t\t.type = SVGA3D_RT_DEPTH\n");
       break;
    case SVGA3D_RT_STENCIL:
-      debug_printf("\t\t.type = SVGA3D_RT_STENCIL\n");
+      _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);
+      _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);
+   _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);
+   _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);
+   _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);
+   _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");
+      _debug_printf("\t\t.face = SVGA3D_FACE_INVALID\n");
       break;
    case SVGA3D_FACE_NONE:
-      debug_printf("\t\t.face = SVGA3D_FACE_NONE\n");
+      _debug_printf("\t\t.face = SVGA3D_FACE_NONE\n");
       break;
    case SVGA3D_FACE_FRONT:
-      debug_printf("\t\t.face = SVGA3D_FACE_FRONT\n");
+      _debug_printf("\t\t.face = SVGA3D_FACE_FRONT\n");
       break;
    case SVGA3D_FACE_BACK:
-      debug_printf("\t\t.face = SVGA3D_FACE_BACK\n");
+      _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");
+      _debug_printf("\t\t.face = SVGA3D_FACE_FRONT_BACK\n");
       break;
    case SVGA3D_FACE_MAX:
-      debug_printf("\t\t.face = SVGA3D_FACE_MAX\n");
+      _debug_printf("\t\t.face = SVGA3D_FACE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.face = %i\n", (*cmd).face);
+      _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);
+   _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);
+   _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _debug_printf("\t\t.data.type = SVGA3D_LIGHTTYPE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.data.type = %i\n", (*cmd).data.type);
+      _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);
+   _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);
+   _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);
+   _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);
+   _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);
+   _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");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_COMPILED_DX8\n");
       break;
    case SVGA3D_SHADERTYPE_VS:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
       break;
    case SVGA3D_SHADERTYPE_PS:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
       break;
    case SVGA3D_SHADERTYPE_MAX:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.type = %i\n", (*cmd).type);
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
       break;
    }
-   debug_printf("\t\t.shid = %u\n", (*cmd).shid);
+   _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);
+   _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");
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_OCCLUSION\n");
       break;
    case SVGA3D_QUERYTYPE_MAX:
-      debug_printf("\t\t.type = SVGA3D_QUERYTYPE_MAX\n");
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.type = %i\n", (*cmd).type);
+      _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);
+   _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);
+   _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);
+   _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);
+   _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);
+   _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);
+   _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");
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_OCCLUSION\n");
       break;
    case SVGA3D_QUERYTYPE_MAX:
-      debug_printf("\t\t.type = SVGA3D_QUERYTYPE_MAX\n");
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.type = %i\n", (*cmd).type);
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
       break;
    }
 }
@@ -599,336 +599,336 @@
 {
    switch((*cmd).state) {
    case SVGA3D_RS_INVALID:
-      debug_printf("\t\t.state = SVGA3D_RS_INVALID\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_INVALID\n");
       break;
    case SVGA3D_RS_ZENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_ZENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_ZENABLE\n");
       break;
    case SVGA3D_RS_ZWRITEENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_ZWRITEENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_ZWRITEENABLE\n");
       break;
    case SVGA3D_RS_ALPHATESTENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_ALPHATESTENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_ALPHATESTENABLE\n");
       break;
    case SVGA3D_RS_DITHERENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_DITHERENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_DITHERENABLE\n");
       break;
    case SVGA3D_RS_BLENDENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_BLENDENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_BLENDENABLE\n");
       break;
    case SVGA3D_RS_FOGENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_FOGENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGENABLE\n");
       break;
    case SVGA3D_RS_SPECULARENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_SPECULARENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_SPECULARENABLE\n");
       break;
    case SVGA3D_RS_STENCILENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_STENCILENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILENABLE\n");
       break;
    case SVGA3D_RS_LIGHTINGENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_LIGHTINGENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_LIGHTINGENABLE\n");
       break;
    case SVGA3D_RS_NORMALIZENORMALS:
-      debug_printf("\t\t.state = SVGA3D_RS_NORMALIZENORMALS\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_NORMALIZENORMALS\n");
       break;
    case SVGA3D_RS_POINTSPRITEENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_POINTSPRITEENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSPRITEENABLE\n");
       break;
    case SVGA3D_RS_POINTSCALEENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_POINTSCALEENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSCALEENABLE\n");
       break;
    case SVGA3D_RS_STENCILREF:
-      debug_printf("\t\t.state = SVGA3D_RS_STENCILREF\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILREF\n");
       break;
    case SVGA3D_RS_STENCILMASK:
-      debug_printf("\t\t.state = SVGA3D_RS_STENCILMASK\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILMASK\n");
       break;
    case SVGA3D_RS_STENCILWRITEMASK:
-      debug_printf("\t\t.state = SVGA3D_RS_STENCILWRITEMASK\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILWRITEMASK\n");
       break;
    case SVGA3D_RS_FOGSTART:
-      debug_printf("\t\t.state = SVGA3D_RS_FOGSTART\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGSTART\n");
       break;
    case SVGA3D_RS_FOGEND:
-      debug_printf("\t\t.state = SVGA3D_RS_FOGEND\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGEND\n");
       break;
    case SVGA3D_RS_FOGDENSITY:
-      debug_printf("\t\t.state = SVGA3D_RS_FOGDENSITY\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGDENSITY\n");
       break;
    case SVGA3D_RS_POINTSIZE:
-      debug_printf("\t\t.state = SVGA3D_RS_POINTSIZE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSIZE\n");
       break;
    case SVGA3D_RS_POINTSIZEMIN:
-      debug_printf("\t\t.state = SVGA3D_RS_POINTSIZEMIN\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSIZEMIN\n");
       break;
    case SVGA3D_RS_POINTSIZEMAX:
-      debug_printf("\t\t.state = SVGA3D_RS_POINTSIZEMAX\n");
+      _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");
+      _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");
+      _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");
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSCALE_C\n");
       break;
    case SVGA3D_RS_FOGCOLOR:
-      debug_printf("\t\t.state = SVGA3D_RS_FOGCOLOR\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGCOLOR\n");
       break;
    case SVGA3D_RS_AMBIENT:
-      debug_printf("\t\t.state = SVGA3D_RS_AMBIENT\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_AMBIENT\n");
       break;
    case SVGA3D_RS_CLIPPLANEENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_CLIPPLANEENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_CLIPPLANEENABLE\n");
       break;
    case SVGA3D_RS_FOGMODE:
-      debug_printf("\t\t.state = SVGA3D_RS_FOGMODE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGMODE\n");
       break;
    case SVGA3D_RS_FILLMODE:
-      debug_printf("\t\t.state = SVGA3D_RS_FILLMODE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_FILLMODE\n");
       break;
    case SVGA3D_RS_SHADEMODE:
-      debug_printf("\t\t.state = SVGA3D_RS_SHADEMODE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_SHADEMODE\n");
       break;
    case SVGA3D_RS_LINEPATTERN:
-      debug_printf("\t\t.state = SVGA3D_RS_LINEPATTERN\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_LINEPATTERN\n");
       break;
    case SVGA3D_RS_SRCBLEND:
-      debug_printf("\t\t.state = SVGA3D_RS_SRCBLEND\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_SRCBLEND\n");
       break;
    case SVGA3D_RS_DSTBLEND:
-      debug_printf("\t\t.state = SVGA3D_RS_DSTBLEND\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_DSTBLEND\n");
       break;
    case SVGA3D_RS_BLENDEQUATION:
-      debug_printf("\t\t.state = SVGA3D_RS_BLENDEQUATION\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_BLENDEQUATION\n");
       break;
    case SVGA3D_RS_CULLMODE:
-      debug_printf("\t\t.state = SVGA3D_RS_CULLMODE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_CULLMODE\n");
       break;
    case SVGA3D_RS_ZFUNC:
-      debug_printf("\t\t.state = SVGA3D_RS_ZFUNC\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_ZFUNC\n");
       break;
    case SVGA3D_RS_ALPHAFUNC:
-      debug_printf("\t\t.state = SVGA3D_RS_ALPHAFUNC\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_ALPHAFUNC\n");
       break;
    case SVGA3D_RS_STENCILFUNC:
-      debug_printf("\t\t.state = SVGA3D_RS_STENCILFUNC\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILFUNC\n");
       break;
    case SVGA3D_RS_STENCILFAIL:
-      debug_printf("\t\t.state = SVGA3D_RS_STENCILFAIL\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILFAIL\n");
       break;
    case SVGA3D_RS_STENCILZFAIL:
-      debug_printf("\t\t.state = SVGA3D_RS_STENCILZFAIL\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILZFAIL\n");
       break;
    case SVGA3D_RS_STENCILPASS:
-      debug_printf("\t\t.state = SVGA3D_RS_STENCILPASS\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILPASS\n");
       break;
    case SVGA3D_RS_ALPHAREF:
-      debug_printf("\t\t.state = SVGA3D_RS_ALPHAREF\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_ALPHAREF\n");
       break;
    case SVGA3D_RS_FRONTWINDING:
-      debug_printf("\t\t.state = SVGA3D_RS_FRONTWINDING\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_FRONTWINDING\n");
       break;
    case SVGA3D_RS_COORDINATETYPE:
-      debug_printf("\t\t.state = SVGA3D_RS_COORDINATETYPE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_COORDINATETYPE\n");
       break;
    case SVGA3D_RS_ZBIAS:
-      debug_printf("\t\t.state = SVGA3D_RS_ZBIAS\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_ZBIAS\n");
       break;
    case SVGA3D_RS_RANGEFOGENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_RANGEFOGENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_RANGEFOGENABLE\n");
       break;
    case SVGA3D_RS_COLORWRITEENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE\n");
       break;
    case SVGA3D_RS_VERTEXMATERIALENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_VERTEXMATERIALENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_VERTEXMATERIALENABLE\n");
       break;
    case SVGA3D_RS_DIFFUSEMATERIALSOURCE:
-      debug_printf("\t\t.state = SVGA3D_RS_DIFFUSEMATERIALSOURCE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_DIFFUSEMATERIALSOURCE\n");
       break;
    case SVGA3D_RS_SPECULARMATERIALSOURCE:
-      debug_printf("\t\t.state = SVGA3D_RS_SPECULARMATERIALSOURCE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_SPECULARMATERIALSOURCE\n");
       break;
    case SVGA3D_RS_AMBIENTMATERIALSOURCE:
-      debug_printf("\t\t.state = SVGA3D_RS_AMBIENTMATERIALSOURCE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_AMBIENTMATERIALSOURCE\n");
       break;
    case SVGA3D_RS_EMISSIVEMATERIALSOURCE:
-      debug_printf("\t\t.state = SVGA3D_RS_EMISSIVEMATERIALSOURCE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_EMISSIVEMATERIALSOURCE\n");
       break;
    case SVGA3D_RS_TEXTUREFACTOR:
-      debug_printf("\t\t.state = SVGA3D_RS_TEXTUREFACTOR\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_TEXTUREFACTOR\n");
       break;
    case SVGA3D_RS_LOCALVIEWER:
-      debug_printf("\t\t.state = SVGA3D_RS_LOCALVIEWER\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_LOCALVIEWER\n");
       break;
    case SVGA3D_RS_SCISSORTESTENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_SCISSORTESTENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_SCISSORTESTENABLE\n");
       break;
    case SVGA3D_RS_BLENDCOLOR:
-      debug_printf("\t\t.state = SVGA3D_RS_BLENDCOLOR\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_BLENDCOLOR\n");
       break;
    case SVGA3D_RS_STENCILENABLE2SIDED:
-      debug_printf("\t\t.state = SVGA3D_RS_STENCILENABLE2SIDED\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILENABLE2SIDED\n");
       break;
    case SVGA3D_RS_CCWSTENCILFUNC:
-      debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILFUNC\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILFUNC\n");
       break;
    case SVGA3D_RS_CCWSTENCILFAIL:
-      debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILFAIL\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILFAIL\n");
       break;
    case SVGA3D_RS_CCWSTENCILZFAIL:
-      debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILZFAIL\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILZFAIL\n");
       break;
    case SVGA3D_RS_CCWSTENCILPASS:
-      debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILPASS\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILPASS\n");
       break;
    case SVGA3D_RS_VERTEXBLEND:
-      debug_printf("\t\t.state = SVGA3D_RS_VERTEXBLEND\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_VERTEXBLEND\n");
       break;
    case SVGA3D_RS_SLOPESCALEDEPTHBIAS:
-      debug_printf("\t\t.state = SVGA3D_RS_SLOPESCALEDEPTHBIAS\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_SLOPESCALEDEPTHBIAS\n");
       break;
    case SVGA3D_RS_DEPTHBIAS:
-      debug_printf("\t\t.state = SVGA3D_RS_DEPTHBIAS\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_DEPTHBIAS\n");
       break;
    case SVGA3D_RS_OUTPUTGAMMA:
-      debug_printf("\t\t.state = SVGA3D_RS_OUTPUTGAMMA\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_OUTPUTGAMMA\n");
       break;
    case SVGA3D_RS_ZVISIBLE:
-      debug_printf("\t\t.state = SVGA3D_RS_ZVISIBLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_ZVISIBLE\n");
       break;
    case SVGA3D_RS_LASTPIXEL:
-      debug_printf("\t\t.state = SVGA3D_RS_LASTPIXEL\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_LASTPIXEL\n");
       break;
    case SVGA3D_RS_CLIPPING:
-      debug_printf("\t\t.state = SVGA3D_RS_CLIPPING\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_CLIPPING\n");
       break;
    case SVGA3D_RS_WRAP0:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP0\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP0\n");
       break;
    case SVGA3D_RS_WRAP1:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP1\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP1\n");
       break;
    case SVGA3D_RS_WRAP2:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP2\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP2\n");
       break;
    case SVGA3D_RS_WRAP3:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP3\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP3\n");
       break;
    case SVGA3D_RS_WRAP4:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP4\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP4\n");
       break;
    case SVGA3D_RS_WRAP5:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP5\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP5\n");
       break;
    case SVGA3D_RS_WRAP6:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP6\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP6\n");
       break;
    case SVGA3D_RS_WRAP7:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP7\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP7\n");
       break;
    case SVGA3D_RS_WRAP8:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP8\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP8\n");
       break;
    case SVGA3D_RS_WRAP9:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP9\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP9\n");
       break;
    case SVGA3D_RS_WRAP10:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP10\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP10\n");
       break;
    case SVGA3D_RS_WRAP11:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP11\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP11\n");
       break;
    case SVGA3D_RS_WRAP12:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP12\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP12\n");
       break;
    case SVGA3D_RS_WRAP13:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP13\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP13\n");
       break;
    case SVGA3D_RS_WRAP14:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP14\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP14\n");
       break;
    case SVGA3D_RS_WRAP15:
-      debug_printf("\t\t.state = SVGA3D_RS_WRAP15\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP15\n");
       break;
    case SVGA3D_RS_MULTISAMPLEANTIALIAS:
-      debug_printf("\t\t.state = SVGA3D_RS_MULTISAMPLEANTIALIAS\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_MULTISAMPLEANTIALIAS\n");
       break;
    case SVGA3D_RS_MULTISAMPLEMASK:
-      debug_printf("\t\t.state = SVGA3D_RS_MULTISAMPLEMASK\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_MULTISAMPLEMASK\n");
       break;
    case SVGA3D_RS_INDEXEDVERTEXBLENDENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_INDEXEDVERTEXBLENDENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_INDEXEDVERTEXBLENDENABLE\n");
       break;
    case SVGA3D_RS_TWEENFACTOR:
-      debug_printf("\t\t.state = SVGA3D_RS_TWEENFACTOR\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_TWEENFACTOR\n");
       break;
    case SVGA3D_RS_ANTIALIASEDLINEENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_ANTIALIASEDLINEENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_ANTIALIASEDLINEENABLE\n");
       break;
    case SVGA3D_RS_COLORWRITEENABLE1:
-      debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE1\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE1\n");
       break;
    case SVGA3D_RS_COLORWRITEENABLE2:
-      debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE2\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE2\n");
       break;
    case SVGA3D_RS_COLORWRITEENABLE3:
-      debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE3\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE3\n");
       break;
    case SVGA3D_RS_SEPARATEALPHABLENDENABLE:
-      debug_printf("\t\t.state = SVGA3D_RS_SEPARATEALPHABLENDENABLE\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_SEPARATEALPHABLENDENABLE\n");
       break;
    case SVGA3D_RS_SRCBLENDALPHA:
-      debug_printf("\t\t.state = SVGA3D_RS_SRCBLENDALPHA\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_SRCBLENDALPHA\n");
       break;
    case SVGA3D_RS_DSTBLENDALPHA:
-      debug_printf("\t\t.state = SVGA3D_RS_DSTBLENDALPHA\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_DSTBLENDALPHA\n");
       break;
    case SVGA3D_RS_BLENDEQUATIONALPHA:
-      debug_printf("\t\t.state = SVGA3D_RS_BLENDEQUATIONALPHA\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_BLENDEQUATIONALPHA\n");
       break;
    case SVGA3D_RS_MAX:
-      debug_printf("\t\t.state = SVGA3D_RS_MAX\n");
+      _debug_printf("\t\t.state = SVGA3D_RS_MAX\n");
       break;
    default:
-      debug_printf("\t\t.state = %i\n", (*cmd).state);
+      _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);
+   _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);
+   _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);
+   _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");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_COMPILED_DX8\n");
       break;
    case SVGA3D_SHADERTYPE_VS:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
       break;
    case SVGA3D_SHADERTYPE_PS:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
       break;
    case SVGA3D_SHADERTYPE_MAX:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.type = %i\n", (*cmd).type);
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
       break;
    }
 }
@@ -936,53 +936,53 @@
 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);
+   _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");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_COMPILED_DX8\n");
       break;
    case SVGA3D_SHADERTYPE_VS:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
       break;
    case SVGA3D_SHADERTYPE_PS:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
       break;
    case SVGA3D_SHADERTYPE_MAX:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.type = %i\n", (*cmd).type);
+      _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]);
+      _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]);
+      _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]);
+      _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]);
+      _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;
    }
 }
@@ -990,25 +990,25 @@
 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);
+   _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);
+   _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);
+   _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
@@ -1016,86 +1016,86 @@
 {
    switch((*cmd).primType) {
    case SVGA3D_PRIMITIVE_INVALID:
-      debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_INVALID\n");
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_INVALID\n");
       break;
    case SVGA3D_PRIMITIVE_TRIANGLELIST:
-      debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_TRIANGLELIST\n");
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_TRIANGLELIST\n");
       break;
    case SVGA3D_PRIMITIVE_POINTLIST:
-      debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_POINTLIST\n");
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_POINTLIST\n");
       break;
    case SVGA3D_PRIMITIVE_LINELIST:
-      debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_LINELIST\n");
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_LINELIST\n");
       break;
    case SVGA3D_PRIMITIVE_LINESTRIP:
-      debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_LINESTRIP\n");
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_LINESTRIP\n");
       break;
    case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
-      debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_TRIANGLESTRIP\n");
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_TRIANGLESTRIP\n");
       break;
    case SVGA3D_PRIMITIVE_TRIANGLEFAN:
-      debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_TRIANGLEFAN\n");
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_TRIANGLEFAN\n");
       break;
    case SVGA3D_PRIMITIVE_MAX:
-      debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_MAX\n");
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.primType = %i\n", (*cmd).primType);
+      _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);
+   _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);
+   _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);
+   _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);
+   _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");
+      _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");
+      _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");
+      _debug_printf("\t\t.mode = SVGA3D_STRETCH_BLT_MAX\n");
       break;
    default:
-      debug_printf("\t\t.mode = %i\n", (*cmd).mode);
+      _debug_printf("\t\t.mode = %i\n", (*cmd).mode);
       break;
    }
 }
@@ -1103,21 +1103,21 @@
 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);
+   _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");
+      _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");
+      _debug_printf("\t\t.transfer = SVGA3D_READ_HOST_VRAM\n");
       break;
    default:
-      debug_printf("\t\t.transfer = %i\n", (*cmd).transfer);
+      _debug_printf("\t\t.transfer = %i\n", (*cmd).transfer);
       break;
    }
 }
@@ -1125,107 +1125,107 @@
 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);
+   _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);
+   _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");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_INVALID\n");
       break;
    case SVGA3D_TRANSFORM_WORLD:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD\n");
       break;
    case SVGA3D_TRANSFORM_VIEW:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_VIEW\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_VIEW\n");
       break;
    case SVGA3D_TRANSFORM_PROJECTION:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_PROJECTION\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_PROJECTION\n");
       break;
    case SVGA3D_TRANSFORM_TEXTURE0:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE0\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE0\n");
       break;
    case SVGA3D_TRANSFORM_TEXTURE1:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE1\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE1\n");
       break;
    case SVGA3D_TRANSFORM_TEXTURE2:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE2\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE2\n");
       break;
    case SVGA3D_TRANSFORM_TEXTURE3:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE3\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE3\n");
       break;
    case SVGA3D_TRANSFORM_TEXTURE4:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE4\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE4\n");
       break;
    case SVGA3D_TRANSFORM_TEXTURE5:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE5\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE5\n");
       break;
    case SVGA3D_TRANSFORM_TEXTURE6:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE6\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE6\n");
       break;
    case SVGA3D_TRANSFORM_TEXTURE7:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE7\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE7\n");
       break;
    case SVGA3D_TRANSFORM_WORLD1:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD1\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD1\n");
       break;
    case SVGA3D_TRANSFORM_WORLD2:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD2\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD2\n");
       break;
    case SVGA3D_TRANSFORM_WORLD3:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD3\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD3\n");
       break;
    case SVGA3D_TRANSFORM_MAX:
-      debug_printf("\t\t.type = SVGA3D_TRANSFORM_MAX\n");
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_MAX\n");
       break;
    default:
-      debug_printf("\t\t.type = %i\n", (*cmd).type);
+      _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]);
+   _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);
+   _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");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_COMPILED_DX8\n");
       break;
    case SVGA3D_SHADERTYPE_VS:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
       break;
    case SVGA3D_SHADERTYPE_PS:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
       break;
    case SVGA3D_SHADERTYPE_MAX:
-      debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
       break;
    default:
-      debug_printf("\t\t.type = %i\n", (*cmd).type);
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
       break;
    }
 }
@@ -1233,187 +1233,519 @@
 static void
 dump_SVGA3dCmdDestroyContext(const SVGA3dCmdDestroyContext *cmd)
 {
-   debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _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);
+   _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");
+      _debug_printf("\t\t.clearFlag = SVGA3D_CLEAR_COLOR\n");
       break;
    case SVGA3D_CLEAR_DEPTH:
-      debug_printf("\t\t.clearFlag = SVGA3D_CLEAR_DEPTH\n");
+      _debug_printf("\t\t.clearFlag = SVGA3D_CLEAR_DEPTH\n");
       break;
    case SVGA3D_CLEAR_STENCIL:
-      debug_printf("\t\t.clearFlag = SVGA3D_CLEAR_STENCIL\n");
+      _debug_printf("\t\t.clearFlag = SVGA3D_CLEAR_STENCIL\n");
       break;
    default:
-      debug_printf("\t\t.clearFlag = %i\n", (*cmd).clearFlag);
+      _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);
+   _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);
+   _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");
+      _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");
+      _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");
+      _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");
+      _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");
+      _debug_printf("\t\t.surfaceFlags = SVGA3D_SURFACE_HINT_VERTEXBUFFER\n");
       break;
    default:
-      debug_printf("\t\t.surfaceFlags = %i\n", (*cmd).surfaceFlags);
+      _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");
+      _debug_printf("\t\t.format = SVGA3D_FORMAT_INVALID\n");
       break;
    case SVGA3D_X8R8G8B8:
-      debug_printf("\t\t.format = SVGA3D_X8R8G8B8\n");
+      _debug_printf("\t\t.format = SVGA3D_X8R8G8B8\n");
       break;
    case SVGA3D_A8R8G8B8:
-      debug_printf("\t\t.format = SVGA3D_A8R8G8B8\n");
+      _debug_printf("\t\t.format = SVGA3D_A8R8G8B8\n");
       break;
    case SVGA3D_R5G6B5:
-      debug_printf("\t\t.format = SVGA3D_R5G6B5\n");
+      _debug_printf("\t\t.format = SVGA3D_R5G6B5\n");
       break;
    case SVGA3D_X1R5G5B5:
-      debug_printf("\t\t.format = SVGA3D_X1R5G5B5\n");
+      _debug_printf("\t\t.format = SVGA3D_X1R5G5B5\n");
       break;
    case SVGA3D_A1R5G5B5:
-      debug_printf("\t\t.format = SVGA3D_A1R5G5B5\n");
+      _debug_printf("\t\t.format = SVGA3D_A1R5G5B5\n");
       break;
    case SVGA3D_A4R4G4B4:
-      debug_printf("\t\t.format = SVGA3D_A4R4G4B4\n");
+      _debug_printf("\t\t.format = SVGA3D_A4R4G4B4\n");
       break;
    case SVGA3D_Z_D32:
-      debug_printf("\t\t.format = SVGA3D_Z_D32\n");
+      _debug_printf("\t\t.format = SVGA3D_Z_D32\n");
       break;
    case SVGA3D_Z_D16:
-      debug_printf("\t\t.format = SVGA3D_Z_D16\n");
+      _debug_printf("\t\t.format = SVGA3D_Z_D16\n");
       break;
    case SVGA3D_Z_D24S8:
-      debug_printf("\t\t.format = SVGA3D_Z_D24S8\n");
+      _debug_printf("\t\t.format = SVGA3D_Z_D24S8\n");
       break;
    case SVGA3D_Z_D15S1:
-      debug_printf("\t\t.format = SVGA3D_Z_D15S1\n");
+      _debug_printf("\t\t.format = SVGA3D_Z_D15S1\n");
       break;
    case SVGA3D_LUMINANCE8:
-      debug_printf("\t\t.format = SVGA3D_LUMINANCE8\n");
+      _debug_printf("\t\t.format = SVGA3D_LUMINANCE8\n");
       break;
    case SVGA3D_LUMINANCE4_ALPHA4:
-      debug_printf("\t\t.format = SVGA3D_LUMINANCE4_ALPHA4\n");
+      _debug_printf("\t\t.format = SVGA3D_LUMINANCE4_ALPHA4\n");
       break;
    case SVGA3D_LUMINANCE16:
-      debug_printf("\t\t.format = SVGA3D_LUMINANCE16\n");
+      _debug_printf("\t\t.format = SVGA3D_LUMINANCE16\n");
       break;
    case SVGA3D_LUMINANCE8_ALPHA8:
-      debug_printf("\t\t.format = SVGA3D_LUMINANCE8_ALPHA8\n");
+      _debug_printf("\t\t.format = SVGA3D_LUMINANCE8_ALPHA8\n");
       break;
    case SVGA3D_DXT1:
-      debug_printf("\t\t.format = SVGA3D_DXT1\n");
+      _debug_printf("\t\t.format = SVGA3D_DXT1\n");
       break;
    case SVGA3D_DXT2:
-      debug_printf("\t\t.format = SVGA3D_DXT2\n");
+      _debug_printf("\t\t.format = SVGA3D_DXT2\n");
       break;
    case SVGA3D_DXT3:
-      debug_printf("\t\t.format = SVGA3D_DXT3\n");
+      _debug_printf("\t\t.format = SVGA3D_DXT3\n");
       break;
    case SVGA3D_DXT4:
-      debug_printf("\t\t.format = SVGA3D_DXT4\n");
+      _debug_printf("\t\t.format = SVGA3D_DXT4\n");
       break;
    case SVGA3D_DXT5:
-      debug_printf("\t\t.format = SVGA3D_DXT5\n");
+      _debug_printf("\t\t.format = SVGA3D_DXT5\n");
       break;
    case SVGA3D_BUMPU8V8:
-      debug_printf("\t\t.format = SVGA3D_BUMPU8V8\n");
+      _debug_printf("\t\t.format = SVGA3D_BUMPU8V8\n");
       break;
    case SVGA3D_BUMPL6V5U5:
-      debug_printf("\t\t.format = SVGA3D_BUMPL6V5U5\n");
+      _debug_printf("\t\t.format = SVGA3D_BUMPL6V5U5\n");
       break;
    case SVGA3D_BUMPX8L8V8U8:
-      debug_printf("\t\t.format = SVGA3D_BUMPX8L8V8U8\n");
+      _debug_printf("\t\t.format = SVGA3D_BUMPX8L8V8U8\n");
       break;
    case SVGA3D_BUMPL8V8U8:
-      debug_printf("\t\t.format = SVGA3D_BUMPL8V8U8\n");
+      _debug_printf("\t\t.format = SVGA3D_BUMPL8V8U8\n");
       break;
    case SVGA3D_ARGB_S10E5:
-      debug_printf("\t\t.format = SVGA3D_ARGB_S10E5\n");
+      _debug_printf("\t\t.format = SVGA3D_ARGB_S10E5\n");
       break;
    case SVGA3D_ARGB_S23E8:
-      debug_printf("\t\t.format = SVGA3D_ARGB_S23E8\n");
+      _debug_printf("\t\t.format = SVGA3D_ARGB_S23E8\n");
       break;
    case SVGA3D_A2R10G10B10:
-      debug_printf("\t\t.format = SVGA3D_A2R10G10B10\n");
+      _debug_printf("\t\t.format = SVGA3D_A2R10G10B10\n");
       break;
    case SVGA3D_V8U8:
-      debug_printf("\t\t.format = SVGA3D_V8U8\n");
+      _debug_printf("\t\t.format = SVGA3D_V8U8\n");
       break;
    case SVGA3D_Q8W8V8U8:
-      debug_printf("\t\t.format = SVGA3D_Q8W8V8U8\n");
+      _debug_printf("\t\t.format = SVGA3D_Q8W8V8U8\n");
       break;
    case SVGA3D_CxV8U8:
-      debug_printf("\t\t.format = SVGA3D_CxV8U8\n");
+      _debug_printf("\t\t.format = SVGA3D_CxV8U8\n");
       break;
    case SVGA3D_X8L8V8U8:
-      debug_printf("\t\t.format = SVGA3D_X8L8V8U8\n");
+      _debug_printf("\t\t.format = SVGA3D_X8L8V8U8\n");
       break;
    case SVGA3D_A2W10V10U10:
-      debug_printf("\t\t.format = SVGA3D_A2W10V10U10\n");
+      _debug_printf("\t\t.format = SVGA3D_A2W10V10U10\n");
       break;
    case SVGA3D_ALPHA8:
-      debug_printf("\t\t.format = SVGA3D_ALPHA8\n");
+      _debug_printf("\t\t.format = SVGA3D_ALPHA8\n");
       break;
    case SVGA3D_R_S10E5:
-      debug_printf("\t\t.format = SVGA3D_R_S10E5\n");
+      _debug_printf("\t\t.format = SVGA3D_R_S10E5\n");
       break;
    case SVGA3D_R_S23E8:
-      debug_printf("\t\t.format = SVGA3D_R_S23E8\n");
+      _debug_printf("\t\t.format = SVGA3D_R_S23E8\n");
       break;
    case SVGA3D_RG_S10E5:
-      debug_printf("\t\t.format = SVGA3D_RG_S10E5\n");
+      _debug_printf("\t\t.format = SVGA3D_RG_S10E5\n");
       break;
    case SVGA3D_RG_S23E8:
-      debug_printf("\t\t.format = SVGA3D_RG_S23E8\n");
+      _debug_printf("\t\t.format = SVGA3D_RG_S23E8\n");
       break;
    case SVGA3D_BUFFER:
-      debug_printf("\t\t.format = SVGA3D_BUFFER\n");
+      _debug_printf("\t\t.format = SVGA3D_BUFFER\n");
       break;
    case SVGA3D_Z_D24X8:
-      debug_printf("\t\t.format = SVGA3D_Z_D24X8\n");
+      _debug_printf("\t\t.format = SVGA3D_Z_D24X8\n");
       break;
    case SVGA3D_FORMAT_MAX:
-      debug_printf("\t\t.format = SVGA3D_FORMAT_MAX\n");
+      _debug_printf("\t\t.format = SVGA3D_FORMAT_MAX\n");
       break;
    default:
-      debug_printf("\t\t.format = %i\n", (*cmd).format);
+      _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);
+   _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++);
 }
 
 
@@ -1432,303 +1764,19 @@
          const SVGA3dCmdHeader *header = (const SVGA3dCmdHeader *)next;
          const uint8_t *body = (const uint8_t *)&header[1];
 
-         next = (const uint8_t *)body + header->size;
+         next = body + header->size;
          if(next > last)
             break;
 
-         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;
-         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++);
+         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]);
+         _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);
+         _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
index 69a8702..ca01543 100644
--- a/src/gallium/drivers/svga/svgadump/svga_dump.h
+++ b/src/gallium/drivers/svga/svgadump/svga_dump.h
@@ -28,6 +28,9 @@
 
 #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);
 
diff --git a/src/gallium/drivers/svga/svgadump/svga_dump.py b/src/gallium/drivers/svga/svgadump/svga_dump.py
index 288e753..0bc0b3a 100755
--- a/src/gallium/drivers/svga/svgadump/svga_dump.py
+++ b/src/gallium/drivers/svga/svgadump/svga_dump.py
@@ -71,14 +71,14 @@
             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 '      _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 '      _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)
+            print '   _debug_printf("\\t\\t%s = %%i\\n", %s);' % (self._instance, "(*cmd)" + self._instance)
 
 
 def dump_decl(instance, decl):
@@ -154,7 +154,7 @@
         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)
+        print '   _debug_printf("\\t\\t%s = %s\\n", %s);' % (self.instance, format, "(*cmd)" + self.instance)
 
 
 def dump_type(instance, type_):
@@ -202,11 +202,62 @@
     ('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;
@@ -221,59 +272,19 @@
          const SVGA3dCmdHeader *header = (const SVGA3dCmdHeader *)next;
          const uint8_t *body = (const uint8_t *)&header[1];
 
-         next = (const uint8_t *)body + header->size;
+         next = body + header->size;
          if(next > last)
             break;
-'''
 
-    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 '               sh_svga_dump((const uint32_t *)body, (unsigned)(next - body)/sizeof(uint32_t));'
-            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++);
+         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]);
+         _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);
+         _debug_printf("\t0x%08x\n", cmd_id);
          next += sizeof(uint32_t);
       }
    }
@@ -294,18 +305,18 @@
     print '#include "svga_shader_dump.h"'
     print '#include "svga3d_reg.h"'
     print
-    print '#include "pipe/p_debug.h"'
+    print '#include "util/u_debug.h"'
     print '#include "svga_dump.h"'
     print
 
     config = parser.config_t(
-        include_paths = ['include'],
+        include_paths = ['../../../include', '../include'],
         compiler = 'gcc',
     )
 
     headers = [
-        'include/svga_types.h', 
-        'include/svga3d_reg.h', 
+        'svga_types.h', 
+        'svga3d_reg.h', 
     ]
 
     decls = parser.parse(headers, config, parser.COMPILATION_MODE.ALL_AT_ONCE)
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
index b0e7fdf..70e27d8 100644
--- a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
@@ -50,16 +50,16 @@
    assert( op.is_reg == 0 );
 
    if (op.coissue)
-      debug_printf( "+" );
-   debug_printf( "%s", mnemonic );
+      _debug_printf( "+" );
+   _debug_printf( "%s", mnemonic );
    switch (op.control) {
    case 0:
       break;
    case SVGA3DOPCONT_PROJECT:
-      debug_printf( "p" );
+      _debug_printf( "p" );
       break;
    case SVGA3DOPCONT_BIAS:
-      debug_printf( "b" );
+      _debug_printf( "b" );
       break;
    default:
       assert( 0 );
@@ -72,28 +72,28 @@
    assert( op.is_reg == 0 );
 
    if (op.coissue)
-      debug_printf( "+" );
-   debug_printf( "%s", mnemonic );
+      _debug_printf( "+" );
+   _debug_printf( "%s", mnemonic );
    switch (op.control) {
    case SVGA3DOPCOMP_RESERVED0:
       break;
    case SVGA3DOPCOMP_GT:
-      debug_printf("_gt");
+      _debug_printf("_gt");
       break;
    case SVGA3DOPCOMP_EQ:
-      debug_printf("_eq");
+      _debug_printf("_eq");
       break;
    case SVGA3DOPCOMP_GE:
-      debug_printf("_ge");
+      _debug_printf("_ge");
       break;
    case SVGA3DOPCOMP_LT:
-      debug_printf("_lt");
+      _debug_printf("_lt");
       break;
    case SVGA3DOPCOMPC_NE:
-      debug_printf("_ne");
+      _debug_printf("_ne");
       break;
    case SVGA3DOPCOMP_LE:
-      debug_printf("_le");
+      _debug_printf("_le");
       break;
    case SVGA3DOPCOMP_RESERVED1:
    default:
@@ -109,93 +109,93 @@
 
    switch (sh_reg_type( reg )) {
    case SVGA3DREG_TEMP:
-      debug_printf( "r%u", reg.number );
+      _debug_printf( "r%u", reg.number );
       break;
 
    case SVGA3DREG_INPUT:
-      debug_printf( "v%u", reg.number );
+      _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 );
+            _debug_printf( "c[aL+%u]", reg.number );
          else
-            debug_printf( "c[a%u.x+%u]", indreg->number, reg.number );
+            _debug_printf( "c[a%u.x+%u]", indreg->number, reg.number );
       }
       else
-         debug_printf( "c%u", reg.number );
+         _debug_printf( "c%u", reg.number );
       break;
 
    case SVGA3DREG_ADDR:    /* VS */
    /* SVGA3DREG_TEXTURE */ /* PS */
       if (di->is_ps)
-         debug_printf( "t%u", reg.number );
+         _debug_printf( "t%u", reg.number );
       else
-         debug_printf( "a%u", reg.number );
+         _debug_printf( "a%u", reg.number );
       break;
 
    case SVGA3DREG_RASTOUT:
       switch (reg.number) {
       case 0 /*POSITION*/:
-         debug_printf( "oPos" );
+         _debug_printf( "oPos" );
          break;
       case 1 /*FOG*/:
-         debug_printf( "oFog" );
+         _debug_printf( "oFog" );
          break;
       case 2 /*POINT_SIZE*/:
-         debug_printf( "oPts" );
+         _debug_printf( "oPts" );
          break;
       default:
          assert( 0 );
-         debug_printf( "???" );
+         _debug_printf( "???" );
       }
       break;
 
    case SVGA3DREG_ATTROUT:
       assert( reg.number < 2 );
-      debug_printf( "oD%u", reg.number );
+      _debug_printf( "oD%u", reg.number );
       break;
 
    case SVGA3DREG_TEXCRDOUT:
    /* SVGA3DREG_OUTPUT */
-      debug_printf( "oT%u", reg.number );
+      _debug_printf( "oT%u", reg.number );
       break;
 
    case SVGA3DREG_COLOROUT:
-      debug_printf( "oC%u", reg.number );
+      _debug_printf( "oC%u", reg.number );
       break;
 
    case SVGA3DREG_DEPTHOUT:
-      debug_printf( "oD%u", reg.number );
+      _debug_printf( "oD%u", reg.number );
       break;
 
    case SVGA3DREG_SAMPLER:
-      debug_printf( "s%u", reg.number );
+      _debug_printf( "s%u", reg.number );
       break;
 
    case SVGA3DREG_CONSTBOOL:
       assert( !reg.relative );
-      debug_printf( "b%u", reg.number );
+      _debug_printf( "b%u", reg.number );
       break;
 
    case SVGA3DREG_CONSTINT:
       assert( !reg.relative );
-      debug_printf( "i%u", reg.number );
+      _debug_printf( "i%u", reg.number );
       break;
 
    case SVGA3DREG_LOOP:
       assert( reg.number == 0 );
-      debug_printf( "aL" );
+      _debug_printf( "aL" );
       break;
 
    case SVGA3DREG_MISCTYPE:
       switch (reg.number) {
       case SVGA3DMISCREG_POSITION:
-         debug_printf( "vPos" );
+         _debug_printf( "vPos" );
          break;
       case SVGA3DMISCREG_FACE:
-         debug_printf( "vFace" );
+         _debug_printf( "vFace" );
          break;
       default:
          assert(0);
@@ -204,46 +204,46 @@
       break;
 
    case SVGA3DREG_LABEL:
-      debug_printf( "l%u", reg.number );
+      _debug_printf( "l%u", reg.number );
       break;
 
    case SVGA3DREG_PREDICATE:
-      debug_printf( "p%u", reg.number );
+      _debug_printf( "p%u", reg.number );
       break;
 
 
    default:
       assert( 0 );
-      debug_printf( "???" );
+      _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] );
+   _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] );
+   _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" );
+   _debug_printf( bdata ? "TRUE" : "FALSE" );
 }
 
 static void dump_sampleinfo( struct ps_sampleinfo sampleinfo )
 {
    switch (sampleinfo.texture_type) {
    case SVGA3DSAMP_2D:
-      debug_printf( "_2d" );
+      _debug_printf( "_2d" );
       break;
    case SVGA3DSAMP_CUBE:
-      debug_printf( "_cube" );
+      _debug_printf( "_cube" );
       break;
    case SVGA3DSAMP_VOLUME:
-      debug_printf( "_volume" );
+      _debug_printf( "_volume" );
       break;
    default:
       assert( 0 );
@@ -255,46 +255,46 @@
 {
    switch (semantic.usage) {
    case SVGA3D_DECLUSAGE_POSITION:
-      debug_printf("_position" );
+      _debug_printf("_position" );
       break;
    case SVGA3D_DECLUSAGE_BLENDWEIGHT:
-      debug_printf("_blendweight" );
+      _debug_printf("_blendweight" );
       break;
    case SVGA3D_DECLUSAGE_BLENDINDICES:
-      debug_printf("_blendindices" );
+      _debug_printf("_blendindices" );
       break;
    case SVGA3D_DECLUSAGE_NORMAL:
-      debug_printf("_normal" );
+      _debug_printf("_normal" );
       break;
    case SVGA3D_DECLUSAGE_PSIZE:
-      debug_printf("_psize" );
+      _debug_printf("_psize" );
       break;
    case SVGA3D_DECLUSAGE_TEXCOORD:
-      debug_printf("_texcoord");
+      _debug_printf("_texcoord");
       break;
    case SVGA3D_DECLUSAGE_TANGENT:
-      debug_printf("_tangent" );
+      _debug_printf("_tangent" );
       break;
    case SVGA3D_DECLUSAGE_BINORMAL:
-      debug_printf("_binormal" );
+      _debug_printf("_binormal" );
       break;
    case SVGA3D_DECLUSAGE_TESSFACTOR:
-      debug_printf("_tessfactor" );
+      _debug_printf("_tessfactor" );
       break;
    case SVGA3D_DECLUSAGE_POSITIONT:
-      debug_printf("_positiont" );
+      _debug_printf("_positiont" );
       break;
    case SVGA3D_DECLUSAGE_COLOR:
-      debug_printf("_color" );
+      _debug_printf("_color" );
       break;
    case SVGA3D_DECLUSAGE_FOG:
-      debug_printf("_fog" );
+      _debug_printf("_fog" );
       break;
    case SVGA3D_DECLUSAGE_DEPTH:
-      debug_printf("_depth" );
+      _debug_printf("_depth" );
       break;
    case SVGA3D_DECLUSAGE_SAMPLE:
-      debug_printf("_sample");
+      _debug_printf("_sample");
       break;
    default:
       assert( 0 );
@@ -302,7 +302,7 @@
    }
 
    if (semantic.usage_index != 0) {
-      debug_printf("%d", semantic.usage_index );
+      _debug_printf("%d", semantic.usage_index );
    }
 }
 
@@ -316,47 +316,47 @@
    assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier );
 
    if (dstreg.modifier & SVGA3DDSTMOD_SATURATE)
-      debug_printf( "_sat" );
+      _debug_printf( "_sat" );
    if (dstreg.modifier & SVGA3DDSTMOD_PARTIALPRECISION)
-      debug_printf( "_pp" );
+      _debug_printf( "_pp" );
    switch (dstreg.shift_scale) {
    case 0:
       break;
    case 1:
-      debug_printf( "_x2" );
+      _debug_printf( "_x2" );
       break;
    case 2:
-      debug_printf( "_x4" );
+      _debug_printf( "_x4" );
       break;
    case 3:
-      debug_printf( "_x8" );
+      _debug_printf( "_x8" );
       break;
    case 13:
-      debug_printf( "_d8" );
+      _debug_printf( "_d8" );
       break;
    case 14:
-      debug_printf( "_d4" );
+      _debug_printf( "_d4" );
       break;
    case 15:
-      debug_printf( "_d2" );
+      _debug_printf( "_d2" );
       break;
    default:
       assert( 0 );
    }
-   debug_printf( " " );
+   _debug_printf( " " );
 
    u.dstreg = dstreg;
    dump_reg( u.reg, NULL, di );
    if (dstreg.write_mask != SVGA3DWRITEMASK_ALL) {
-      debug_printf( "." );
+      _debug_printf( "." );
       if (dstreg.write_mask & SVGA3DWRITEMASK_0)
-         debug_printf( "x" );
+         _debug_printf( "x" );
       if (dstreg.write_mask & SVGA3DWRITEMASK_1)
-         debug_printf( "y" );
+         _debug_printf( "y" );
       if (dstreg.write_mask & SVGA3DWRITEMASK_2)
-         debug_printf( "z" );
+         _debug_printf( "z" );
       if (dstreg.write_mask & SVGA3DWRITEMASK_3)
-         debug_printf( "w" );
+         _debug_printf( "w" );
    }
 }
 
@@ -372,19 +372,19 @@
    case SVGA3DSRCMOD_BIASNEG:
    case SVGA3DSRCMOD_SIGNNEG:
    case SVGA3DSRCMOD_X2NEG:
-      debug_printf( "-" );
+      _debug_printf( "-" );
       break;
    case SVGA3DSRCMOD_ABS:
-      debug_printf( "|" );
+      _debug_printf( "|" );
       break;
    case SVGA3DSRCMOD_ABSNEG:
-      debug_printf( "-|" );
+      _debug_printf( "-|" );
       break;
    case SVGA3DSRCMOD_COMP:
-      debug_printf( "1-" );
+      _debug_printf( "1-" );
       break;
    case SVGA3DSRCMOD_NOT:
-      debug_printf( "!" );
+      _debug_printf( "!" );
    }
 
    u.srcreg = srcreg;
@@ -397,39 +397,39 @@
       break;
    case SVGA3DSRCMOD_ABS:
    case SVGA3DSRCMOD_ABSNEG:
-      debug_printf( "|" );
+      _debug_printf( "|" );
       break;
    case SVGA3DSRCMOD_BIAS:
    case SVGA3DSRCMOD_BIASNEG:
-      debug_printf( "_bias" );
+      _debug_printf( "_bias" );
       break;
    case SVGA3DSRCMOD_SIGN:
    case SVGA3DSRCMOD_SIGNNEG:
-      debug_printf( "_bx2" );
+      _debug_printf( "_bx2" );
       break;
    case SVGA3DSRCMOD_X2:
    case SVGA3DSRCMOD_X2NEG:
-      debug_printf( "_x2" );
+      _debug_printf( "_x2" );
       break;
    case SVGA3DSRCMOD_DZ:
-      debug_printf( "_dz" );
+      _debug_printf( "_dz" );
       break;
    case SVGA3DSRCMOD_DW:
-      debug_printf( "_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( "." );
+      _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] );
+         _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] );
+         _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] );
       }
    }
 }
@@ -447,15 +447,15 @@
 
    if (do_binary) {
       for (i = 0; i < dwords; i++) 
-         debug_printf("  0x%08x,\n", assem[i]);
+         _debug_printf("  0x%08x,\n", assem[i]);
       
-      debug_printf("\n\n");
+      _debug_printf("\n\n");
    }
 
    di.version.value = *assem++;
    di.is_ps = (di.version.type == SVGA3D_PS_TYPE);
 
-   debug_printf(
+   _debug_printf(
       "%s_%u_%u\n",
       di.is_ps ? "ps" : "vs",
       di.version.major,
@@ -465,7 +465,7 @@
       struct sh_op op = *(struct sh_op *) assem;
 
       if (assem - start >= dwords) {
-         debug_printf("... ran off end of buffer\n");
+         _debug_printf("... ran off end of buffer\n");
          assert(0);
          return;
       }
@@ -475,7 +475,7 @@
          {
             struct sh_dcl dcl = *(struct sh_dcl *) assem;
 
-            debug_printf( "dcl" );
+            _debug_printf( "dcl" );
             if (sh_dstreg_type( dcl.reg ) == SVGA3DREG_SAMPLER)
                dump_sampleinfo( dcl.u.ps.sampleinfo );
             else if (di.is_ps) {
@@ -486,7 +486,7 @@
             else
                dump_usageinfo( dcl.u.vs.semantic );
             dump_dstreg( dcl.reg, &di );
-            debug_printf( "\n" );
+            _debug_printf( "\n" );
             assem += sizeof( struct sh_dcl ) / sizeof( unsigned );
          }
          break;
@@ -495,11 +495,11 @@
          {
             struct sh_defb defb = *(struct sh_defb *) assem;
 
-            debug_printf( "defb " );
+            _debug_printf( "defb " );
             dump_reg( defb.reg, NULL, &di );
-            debug_printf( ", " );
+            _debug_printf( ", " );
             dump_bdata( defb.data );
-            debug_printf( "\n" );
+            _debug_printf( "\n" );
             assem += sizeof( struct sh_defb ) / sizeof( unsigned );
          }
          break;
@@ -508,11 +508,11 @@
          {
             struct sh_defi defi = *(struct sh_defi *) assem;
 
-            debug_printf( "defi " );
+            _debug_printf( "defi " );
             dump_reg( defi.reg, NULL, &di );
-            debug_printf( ", " );
+            _debug_printf( ", " );
             dump_idata( defi.idata );
-            debug_printf( "\n" );
+            _debug_printf( "\n" );
             assem += sizeof( struct sh_defi ) / sizeof( unsigned );
          }
          break;
@@ -528,11 +528,11 @@
          else {
             struct sh_unaryop unaryop = *(struct sh_unaryop *) assem;
             dump_dstreg( unaryop.dst, &di );
-            debug_printf( ", " );
+            _debug_printf( ", " );
             dump_srcreg( unaryop.src, NULL, &di );
             assem += sizeof( struct sh_unaryop ) / sizeof( unsigned );
          }
-         debug_printf( "\n" );
+         _debug_printf( "\n" );
          break;
 
       case SVGA3DOP_TEX:
@@ -549,7 +549,7 @@
                struct sh_unaryop unaryop = *(struct sh_unaryop *) assem;
 
                dump_dstreg( unaryop.dst, &di );
-               debug_printf( ", " );
+               _debug_printf( ", " );
                dump_srcreg( unaryop.src, NULL, &di );
                assem += sizeof( struct sh_unaryop ) / sizeof( unsigned );
             }
@@ -559,30 +559,30 @@
 
             dump_op( op, "texld" );
             dump_dstreg( binaryop.dst, &di );
-            debug_printf( ", " );
+            _debug_printf( ", " );
             dump_srcreg( binaryop.src0, NULL, &di );
-            debug_printf( ", " );
+            _debug_printf( ", " );
             dump_srcreg( binaryop.src1, NULL, &di );
             assem += sizeof( struct sh_binaryop ) / sizeof( unsigned );
          }
-         debug_printf( "\n" );
+         _debug_printf( "\n" );
          break;
 
       case SVGA3DOP_DEF:
          {
             struct sh_def def = *(struct sh_def *) assem;
 
-            debug_printf( "def " );
+            _debug_printf( "def " );
             dump_reg( def.reg, NULL, &di );
-            debug_printf( ", " );
+            _debug_printf( ", " );
             dump_cdata( def.cdata );
-            debug_printf( "\n" );
+            _debug_printf( "\n" );
             assem += sizeof( struct sh_def ) / sizeof( unsigned );
          }
          break;
 
       case SVGA3DOP_PHASE:
-         debug_printf( "phase\n" );
+         _debug_printf( "phase\n" );
          assem += sizeof( struct sh_op ) / sizeof( unsigned );
          break;
 
@@ -596,12 +596,12 @@
          break;
 
       case SVGA3DOP_RET:
-         debug_printf( "ret\n" );
+         _debug_printf( "ret\n" );
          assem += sizeof( struct sh_op ) / sizeof( unsigned );
          break;
 
       case SVGA3DOP_END:
-         debug_printf( "end\n" );
+         _debug_printf( "end\n" );
          finished = TRUE;
          break;
 
@@ -640,14 +640,14 @@
                }
 
                if (not_first_arg)
-                  debug_printf( ", " );
+                  _debug_printf( ", " );
                else
-                  debug_printf( " " );
+                  _debug_printf( " " );
                dump_srcreg( srcreg, &indreg, &di );
                not_first_arg = TRUE;
             }
 
-            debug_printf( "\n" );
+            _debug_printf( "\n" );
          }
       }
    }
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 540855c..075e4f9 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -97,25 +97,6 @@
 
 
 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;
@@ -145,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);
@@ -174,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);
 
@@ -194,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,
@@ -216,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);
 
@@ -234,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,
@@ -260,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);
 
@@ -280,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;
 }
 
 
@@ -308,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);
 
@@ -330,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();
 }
@@ -348,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();
 }
@@ -387,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);
@@ -412,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);
 
@@ -434,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();
 }
@@ -452,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();
 }
@@ -471,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);
 
@@ -482,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();
 }
@@ -512,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();
 }
@@ -531,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);
 
@@ -553,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();
 }
@@ -571,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();
 }
@@ -587,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);
@@ -612,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();
 }
@@ -630,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();
 }
@@ -649,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);
 
@@ -752,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();
 }
@@ -772,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();
 
@@ -792,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();
 }
@@ -810,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();
 }
@@ -882,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();
 }
@@ -900,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();
 }
@@ -918,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();
 }
@@ -936,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;
@@ -961,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();
 }
@@ -1026,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();
 }
@@ -1087,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();
 }
@@ -1130,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);
@@ -1242,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;
@@ -1255,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;
@@ -1276,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_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 0372d92..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"
@@ -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,
@@ -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/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index c36286f..f7368bb 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -167,7 +167,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 fd14dc8..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
@@ -320,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
 
 
 /**
@@ -349,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
@@ -390,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_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/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..1058dd3 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);
@@ -299,8 +299,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 +416,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 +434,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 +458,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 +532,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 +563,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 +636,7 @@
 }
 
 void
-dri_swap_buffers(__DRIdrawablePrivate * dPriv)
+dri_swap_buffers(__DRIdrawable * dPriv)
 {
    struct dri_context *ctx;
    struct pipe_surface *back_surf;
@@ -668,7 +668,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..80bb5d7 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,22 @@
  * 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_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_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index cb864d4..bb12baf 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;
@@ -319,7 +319,7 @@
 }
 
 static void
-dri_destroy_screen(__DRIscreenPrivate * sPriv)
+dri_destroy_screen(__DRIscreen * sPriv)
 {
    struct dri_screen *screen = dri_screen(sPriv);
 
@@ -346,4 +346,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 61b7f98..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"
 
 /*
@@ -114,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);
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..d4fdd43 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -38,10 +38,12 @@
         ],
     )
 
+    env['no_import_lib'] = 1
+
     env.SharedLibrary(
         target = '_gallium',
         source = [
             'st_hardpipe_winsys.c',
         ],
-        LIBS = [pyst, softpipe, trace] + auxiliaries + env['LIBS'],
+        LIBS = [pyst, softpipe, trace] + 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..2dc995a 100644
--- a/src/gallium/state_trackers/python/p_device.i
+++ b/src/gallium/state_trackers/python/p_device.i
@@ -112,10 +112,9 @@
       struct pipe_texture templat;
       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;
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..1ceead5
--- /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_DISPLAY_TARGET,
+    ).get_surface()
+    zbuf = dev.texture_create(
+        PIPE_FORMAT_Z16_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..af80426 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()
@@ -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_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..eed6cdd 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()
@@ -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..41bebd0 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()
@@ -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/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/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/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index a8ab939..e503913 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -31,6 +31,7 @@
 #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"
@@ -51,13 +52,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 |
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_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 6d09501..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;
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/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index a5975aa..1c248a6 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -423,8 +423,6 @@
 
 
 
-
-
 static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
 {
    if (!trans)
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 0160b1a..650d2c0 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -50,6 +50,7 @@
 #endif
 
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_rect.h"
 
 #ifdef HAVE_LIBKMS
@@ -204,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);
@@ -224,7 +224,7 @@
 					    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);
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index 4fa4754..fd82f4f 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -40,6 +40,7 @@
 #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 */
@@ -92,7 +93,7 @@
     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:
@@ -108,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;
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 4e78825..d9432ba 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -43,6 +43,7 @@
 #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"
@@ -202,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);
 
@@ -242,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);
@@ -274,8 +275,8 @@
 	    PIPE_REFERENCED_FOR_WRITE)
 	    exa->pipe->flush(exa->pipe, 0, NULL);
 
-        assert(pPix->drawable.width <= priv->tex->width[0]);
-        assert(pPix->drawable.height <= priv->tex->height[0]);
+        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,
@@ -532,8 +533,8 @@
                            dstX, dstY,
                            srcX, srcY,
                            width, height,
-                           exa->copy.src_texture->width[0],
-                           exa->copy.src_texture->height[0]);
+                           exa->copy.src_texture->width0,
+                           exa->copy.src_texture->height0);
    }
 }
 
@@ -810,34 +811,7 @@
     return 0;
 }
 
-unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
-{
-    ScreenPtr pScreen = pPixmap->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_pixmap_priv *priv;
-    unsigned handle;
-    unsigned stride;
 
-    if (!ms->exa) {
-	FatalError("NO MS->EXA\n");
-	return 0;
-    }
-
-    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;
-}
 
 static Bool
 size_match( int width, int tex_width )
@@ -875,8 +849,8 @@
        
        if (priv->tex)
           debug_printf("  ==> old texture %dx%d\n",
-                       priv->tex->width[0], 
-                       priv->tex->height[0]);
+                       priv->tex->width0, 
+                       priv->tex->height0);
     }
 
 
@@ -904,8 +878,8 @@
     /* Deal with screen resize */
     if ((exa->accel || priv->flags) &&
         (!priv->tex ||
-         !size_match(width, priv->tex->width[0]) ||
-         !size_match(height, priv->tex->height[0]) ||
+         !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;
@@ -913,17 +887,16 @@
 	memset(&template, 0, sizeof(template));
 	template.target = PIPE_TEXTURE_2D;
 	exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &priv->picture_format);
-	pf_get_block(template.format, &template.block);
         if (ROUND_UP_TEXTURES && priv->flags == 0) {
-           template.width[0] = util_next_power_of_two(width);
-           template.height[0] = util_next_power_of_two(height);
+           template.width0 = util_next_power_of_two(width);
+           template.height0 = util_next_power_of_two(height);
         }
         else {
-           template.width[0] = width;
-           template.height[0] = height;
+           template.width0 = width;
+           template.height0 = height;
         }
 
-	template.depth[0] = 1;
+	template.depth0 = 1;
 	template.last_level = 0;
 	template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
 	priv->tex_flags = priv->flags;
@@ -938,12 +911,12 @@
 	    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]));
+                                       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->width[0]),
-                                 min(height, texture->height[0]));
+                                 0, 0, min(width, texture->width0),
+                                 min(height, texture->height0));
             }
 	    exa->scrn->tex_surface_destroy(dst_surf);
 	    exa->scrn->tex_surface_destroy(src_surf);
@@ -976,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);
@@ -999,10 +972,9 @@
     memset(&template, 0, sizeof(template));
     template.target = PIPE_TEXTURE_2D;
     exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &dummy);
-    pf_get_block(template.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.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
     template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 37c8942..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"
@@ -170,14 +171,14 @@
       map_point(src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]);
    }
 
-   s0 =  pt0[0] / src->width[0];
-   s1 =  pt1[0] / src->width[0];
-   s2 =  pt2[0] / src->width[0];
-   s3 =  pt3[0] / src->width[0];
-   t0 =  pt0[1] / src->height[0];
-   t1 =  pt1[1] / src->height[0];
-   t2 =  pt2[1] / src->height[0];
-   t3 =  pt3[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 */
    add_vertex_1tex(r, dstX, dstY, s0, t0);
@@ -248,15 +249,15 @@
       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 */
    add_vertex_2tex(r, dstX, dstY,
@@ -286,10 +287,10 @@
    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 */
    add_vertex_1tex(r, dstX, dstY, s0, t0);
@@ -510,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);
@@ -534,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);
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index c0cfbe6..4d5d478 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -135,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);
 
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index 19c5005..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
@@ -167,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);
@@ -183,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);
    }
 
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/SConscript b/src/gallium/winsys/drm/SConscript
index 9f7b383..66b73a8 100644
--- a/src/gallium/winsys/drm/SConscript
+++ b/src/gallium/winsys/drm/SConscript
@@ -58,6 +58,11 @@
 			'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/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..fc9678d
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
@@ -0,0 +1,243 @@
+
+#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 =
+{
+   .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/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..7106a06 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);
@@ -247,7 +247,7 @@
 		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;
 }
 
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..d2367b2 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,10 +141,15 @@
                                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;
 
+    if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) {
+        priv->flush_cb(priv->flush_data);
+    }
+
     if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
         uint32_t domain;
 
@@ -317,13 +321,10 @@
     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.width0 = w;
+    tmpl.height0 = h;
+    tmpl.depth0 = 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) {
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..05194fc 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;
     }
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/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/core/vmw_surface.c b/src/gallium/winsys/drm/vmware/core/vmw_surface.c
index 64eb32f..5f1b9ad 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_surface.c
+++ b/src/gallium/winsys/drm/vmware/core/vmw_surface.c
@@ -47,7 +47,7 @@
    src_ref = src ? &src->refcnt : NULL;
    dst_ref = dst ? &dst->refcnt : NULL;
 
-   if (pipe_reference(&dst_ref, src_ref)) {
+   if (pipe_reference(dst_ref, src_ref)) {
       vmw_ioctl_surface_destroy(dst->screen, dst->sid);
 #ifdef DEBUG
       /* to detect dangling pointers */
diff --git a/src/gallium/winsys/drm/vmware/dri/SConscript b/src/gallium/winsys/drm/vmware/dri/SConscript
index 1019f57..84319f9 100644
--- a/src/gallium/winsys/drm/vmware/dri/SConscript
+++ b/src/gallium/winsys/drm/vmware/dri/SConscript
@@ -48,7 +48,7 @@
             svgadrm,
             svga,
             mesa,
-            auxiliaries,
+            gallium,
             ])
       
       # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
diff --git a/src/gallium/winsys/drm/vmware/xorg/SConscript b/src/gallium/winsys/drm/vmware/xorg/SConscript
index 5e78c1f..1e5d8ff 100644
--- a/src/gallium/winsys/drm/vmware/xorg/SConscript
+++ b/src/gallium/winsys/drm/vmware/xorg/SConscript
@@ -38,7 +38,7 @@
 		st_xorg,
 		svgadrm,
 		svga,
-                auxiliaries,
+                gallium,
 	])
 
 	sources = [
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index d02f825..599973c 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;
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 917a81c..4cbc86f 100644
--- a/src/gallium/winsys/gdi/SConscript
+++ b/src/gallium/winsys/gdi/SConscript
@@ -47,5 +47,5 @@
     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 a0293fe..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)
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 163cc88..6dbe05f 100644
--- a/src/gallium/winsys/xlib/xlib.c
+++ b/src/gallium/winsys/xlib/xlib.c
@@ -42,7 +42,6 @@
  */
 
 enum mode {
-   MODE_TRACE,
    MODE_CELL,
    MODE_LLVMPIPE,
    MODE_SOFTPIPE
@@ -51,9 +50,6 @@
 
 static enum mode get_mode()
 {
-   if (getenv("XMESA_TRACE"))
-      return MODE_TRACE;
-
 #ifdef GALLIUM_CELL
    if (!getenv("GALLIUM_NOCELL")) 
       return MODE_CELL;
@@ -73,11 +69,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_cell.c b/src/gallium/winsys/xlib/xlib_cell.c
index 5f8dc2a..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,15 +278,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 *
 xm_surface_buffer_create(struct pipe_winsys *winsys,
                          unsigned width, unsigned height,
@@ -295,18 +287,15 @@
                          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/drivers/dri/intel/intel_swapbuffers.h b/src/glsl/cl/sl_cl_parse.h
similarity index 70%
copy from src/mesa/drivers/dri/intel/intel_swapbuffers.h
copy to src/glsl/cl/sl_cl_parse.h
index 75bb624..dd5791d 100644
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.h
+++ b/src/glsl/cl/sl_cl_parse.h
@@ -1,7 +1,6 @@
-
 /**************************************************************************
  * 
- * Copyright 2006 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
@@ -26,27 +25,16 @@
  * 
  **************************************************************************/
 
-#ifndef INTEL_SWAPBUFFERS_H
-#define INTEL_SWAPBUFFERS_H
+#ifndef SL_CL_PARSE_H
+#define SL_CL_PARSE_H
 
-#include "dri_util.h"
-#include "drm.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);
 
-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 */
+#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/drivers/dri/intel/intel_swapbuffers.h b/src/glsl/pp/sl_pp_dict.h
similarity index 67%
copy from src/mesa/drivers/dri/intel/intel_swapbuffers.h
copy to src/glsl/pp/sl_pp_dict.h
index 75bb624..875217b 100644
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.h
+++ b/src/glsl/pp/sl_pp_dict.h
@@ -1,7 +1,6 @@
-
 /**************************************************************************
  * 
- * Copyright 2006 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
@@ -26,27 +25,53 @@
  * 
  **************************************************************************/
 
-#ifndef INTEL_SWAPBUFFERS_H
-#define INTEL_SWAPBUFFERS_H
-
-#include "dri_util.h"
-#include "drm.h"
-
-struct intel_context;
-struct intel_framebuffer;
+#ifndef SL_PP_DICT_H
+#define SL_PP_DICT_H
 
 
-extern void
-intelSwapBuffers(__DRIdrawablePrivate * dPriv);
+struct sl_pp_context;
 
-extern void
-intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h);
+struct sl_pp_dict {
+   int all;
 
-extern GLuint
-intelFixupVblank(struct intel_context *intel, __DRIdrawablePrivate *dPriv);
+   int require;
+   int enable;
+   int warn;
+   int disable;
 
-extern void
-intelWindowMoved(struct intel_context *intel);
+   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 /* INTEL_SWAPBUFFERS_H */
+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/drivers/dri/intel/intel_swapbuffers.h b/src/glsl/pp/sl_pp_expression.h
similarity index 70%
rename from src/mesa/drivers/dri/intel/intel_swapbuffers.h
rename to src/glsl/pp/sl_pp_expression.h
index 75bb624..377d5b4 100644
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.h
+++ b/src/glsl/pp/sl_pp_expression.h
@@ -1,7 +1,6 @@
-
 /**************************************************************************
  * 
- * Copyright 2006 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
@@ -26,27 +25,16 @@
  * 
  **************************************************************************/
 
-#ifndef INTEL_SWAPBUFFERS_H
-#define INTEL_SWAPBUFFERS_H
+#ifndef SL_PP_EXPRESSION_H
+#define SL_PP_EXPRESSION_H
 
-#include "dri_util.h"
-#include "drm.h"
-
-struct intel_context;
-struct intel_framebuffer;
+#include "sl_pp_context.h"
+#include "sl_pp_token.h"
 
 
-extern void
-intelSwapBuffers(__DRIdrawablePrivate * dPriv);
+int
+sl_pp_execute_expression(struct sl_pp_context *context,
+                         const struct sl_pp_token_info *input,
+                         int *result);
 
-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 */
+#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/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_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/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/dri_glx.c b/src/glx/x11/dri_glx.c
index 88487b6..a890fee 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -290,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 *
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 96b4ff8..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)
@@ -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 ca4a9af..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,6 +163,7 @@
 		'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',
@@ -189,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',
@@ -227,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',
@@ -338,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 4ca0e7b..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 */
@@ -265,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 28abcc4..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);
    }
 
@@ -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) {
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/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 547f18a..0e01d74 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,7 +167,7 @@
 			  __DRIdrawable *pdp,
 			  __DRIdrawable *prp)
 {
-    __DRIscreenPrivate *psp = NULL;
+    __DRIscreen *psp = NULL;
 
     /* Bind the drawable to the context */
 
@@ -220,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
@@ -228,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))) {
@@ -309,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().
  */
@@ -497,7 +497,7 @@
 	
 static void dri_put_drawable(__DRIdrawable *pdp)
 {
-    __DRIscreenPrivate *psp;
+    __DRIscreen *psp;
 
     if (pdp) {
 	pdp->refcount--;
@@ -560,7 +560,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.
@@ -841,7 +841,7 @@
     driCreateNewContext,
 };
 
-/** Legacy DRI interface */
+/** DRI2 interface */
 const __DRIdri2Extension driDRI2Extension = {
     { __DRI_DRI2, __DRI_DRI2_VERSION },
     dri2CreateNewScreen,
@@ -849,14 +849,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)
 {
@@ -871,7 +863,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 ) {
@@ -921,14 +913,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..35d8b8f 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;
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/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 e7dd960..8bf5ae4 100644
--- a/src/mesa/drivers/dri/ffb/ffb_tris.c
+++ b/src/mesa/drivers/dri/ffb/ffb_tris.c
@@ -351,7 +351,7 @@
 
 #define LOCAL_VARS(n)				\
    ffbContextPtr fmesa = FFB_CONTEXT(ctx);	\
-   __DRIdrawablePrivate *dPriv = fmesa->driDrawable; \
+   __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/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 ce409b3..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"
@@ -303,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 e8c8d5a..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]) {
@@ -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,9 +696,6 @@
 {
    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 void 
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 25418d5..f55b551 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -318,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_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_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index cc98d12..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]) {
@@ -589,7 +589,7 @@
 
    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]) {
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index 825f1db..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"
@@ -347,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 ff97e5a..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++)
@@ -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,9 +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 void 
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_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index dbd10a5..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,14 +66,13 @@
    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;
@@ -85,7 +85,7 @@
 
    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));
@@ -160,7 +161,7 @@
    /* _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 1c68255..d71bac7 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -118,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 fa9648f..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);
              }
          }
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 cf79224..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++;
    }
@@ -571,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);
@@ -578,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 fded47a..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;
@@ -438,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;
 
@@ -515,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:
     */
@@ -542,6 +551,7 @@
       GLuint clip_start;
       GLuint sf_start;
       GLuint cs_start;
+      GLuint size; /* Hardware URB size, in KB. */
    } urb;
 
    
@@ -669,7 +679,7 @@
  * brw_context.c
  */
 GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
-			    __DRIcontextPrivate *driContextPriv,
+			    __DRIcontext *driContextPriv,
 			    void *sharedContextPrivate);
 
 /*======================================================================
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index aadcfbe..190310a 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -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 c19510b..ea0d7e0 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -832,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 130bd0f..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"
 };
 
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 8bcb608..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
@@ -157,13 +157,13 @@
    }
    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) {
       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,
@@ -339,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;
 
@@ -356,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);
 
@@ -404,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 c66f43a..c773b71 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -243,16 +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,
@@ -504,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 |
@@ -524,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));
 
@@ -537,7 +527,7 @@
       OUT_RELOC(input->bo,
 		I915_GEM_DOMAIN_VERTEX, 0,
 		input->offset);
-      if (BRW_IS_IGDNG(brw)) {
+      if (intel->is_ironlake) {
 	 OUT_RELOC(input->bo,
 		   I915_GEM_DOMAIN_VERTEX, 0,
 		   input->bo->size - 1);
@@ -547,7 +537,7 @@
    }
    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];
@@ -573,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) |
@@ -714,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_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index c8fb0a2..8d6ac00 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -252,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;
@@ -319,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;
@@ -358,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;
@@ -395,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;
@@ -433,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;
@@ -447,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;
@@ -648,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) {
@@ -690,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) {
@@ -803,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)
@@ -846,10 +854,11 @@
 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);
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 610b6c3..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? */
diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h
index 010c1c2..813b8d4 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_gs.h
@@ -63,7 +63,6 @@
    GLuint nr_attrs;
    GLuint nr_regs;
    GLuint nr_bytes;
-   GLboolean need_ff_sync;
 };
 
 #define ATTR_SIZE  (4*4)
diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c
index 0fc5b02..a81b972 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
@@ -122,12 +122,14 @@
 
 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)
+   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));
@@ -145,9 +147,11 @@
 
 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);      
    if (key->pv_first) {
       brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
@@ -165,9 +169,11 @@
 
 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));
@@ -176,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));
@@ -186,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 4b0d598..7b70f78 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -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) |
@@ -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();
@@ -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));
@@ -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 */
@@ -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_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c
index 3eae41e..bb08055 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c
@@ -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);
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index bb69435..09223b7 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -165,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;
@@ -177,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;
@@ -187,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;
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 14d5319..9c9d145 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -151,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_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_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 27aac8b..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,7 +142,7 @@
    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;
@@ -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;
@@ -1113,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;
@@ -1136,7 +1139,7 @@
     * workaround.
     */
    if ((c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_PSIZ)) ||
-       c->key.nr_userclip || BRW_IS_965(p->brw))
+       c->key.nr_userclip || brw->has_negative_rhw_bug)
    {
       struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
       GLuint i;
@@ -1167,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,
@@ -1195,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.
@@ -1359,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;
@@ -1592,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 7285466..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,7 +109,7 @@
    vs.thread3.urb_entry_read_offset = 0;
    vs.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
 
-   if (BRW_IS_IGDNG(brw)) {
+   if (intel->is_ironlake) {
       switch (key->nr_urb_entries) {
       case 8:
       case 12:
@@ -135,7 +135,7 @@
       case 32:
 	 break;
       case 64:
-	 assert(BRW_IS_G4X(brw));
+	 assert(intel->is_g4x);
 	 break;
       default:
 	 assert(0);
@@ -145,17 +145,8 @@
 
    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_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index 34aaea3..72749b3 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -150,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.
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 9dcb6e1..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;
    GLbitfield64 vp_outputs_written;
+   GLuint program_string_id:32;
 };
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index c6d10f5..f316e0c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -830,6 +830,7 @@
 	      GLboolean shadow)
 {
    struct brw_compile *p = &c->func;
+   struct intel_context *intel = &p->brw->intel;
    struct brw_reg dst_retyped;
    GLuint cur_mrf = 2, response_length;
    GLuint i, nr_texcoords;
@@ -873,7 +874,7 @@
    }
 
    /* Pre-Ironlake, the 8-wide sampler always took u,v,r. */
-   if (!BRW_IS_IGDNG(p->brw) && c->dispatch_width == 8)
+   if (!intel->is_ironlake && c->dispatch_width == 8)
       nr_texcoords = 3;
 
    /* For shadow comparisons, we have to supply u,v,r. */
@@ -891,7 +892,7 @@
 
    /* Fill in the shadow comparison reference value. */
    if (shadow) {
-      if (BRW_IS_IGDNG(p->brw)) {
+      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;
@@ -904,7 +905,7 @@
       cur_mrf += mrf_per_channel;
    }
 
-   if (BRW_IS_IGDNG(p->brw)) {
+   if (intel->is_ironlake) {
       if (shadow)
 	 msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_IGDNG;
       else
@@ -944,6 +945,7 @@
 	      GLuint sampler)
 {
    struct brw_compile *p = &c->func;
+   struct intel_context *intel = &p->brw->intel;
    GLuint msgLength;
    GLuint msg_type;
    GLuint mrf_per_channel;
@@ -955,8 +957,8 @@
     * undefined, and trust the execution mask to keep the undefined pixels
     * from mattering.
     */
-   if (c->dispatch_width == 16 || !BRW_IS_IGDNG(p->brw)) {
-      if (BRW_IS_IGDNG(p->brw))
+   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;
@@ -1174,7 +1176,7 @@
    brw_push_insn_state(p);
 
    for (channel = 0; channel < 4; channel++) {
-      if (c->dispatch_width == 16 && (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))) {
+      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.
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 7d03179..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;
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 7e5533e..fde83ee 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -1826,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];
@@ -1876,10 +1877,6 @@
 	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, dst, dst_flags);
@@ -2043,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:
@@ -2096,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_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
index aa2e519..ad267a4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
@@ -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 f89ed9b..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;
@@ -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 afb36b7..f26cfab 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -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;
@@ -578,7 +579,7 @@
       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
@@ -622,7 +623,7 @@
 	    tile_base = ((key.draw_y / 32) * (32 * pitch));
 	    tile_base += (key.draw_x - tile_x) / (128 / key.cpp) * 4096;
 	 }
-	 assert(BRW_IS_G4X(brw) || (tile_x == 0 && tile_y == 0));
+	 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
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 ca6e2fa..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,10 +172,8 @@
       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,
@@ -212,7 +181,7 @@
 
    batch->reserved_space = 0;
    /* Emit a flush if the bufmgr doesn't do it for us. */
-   if (intel->always_flush_cache || !intel->ttm) {
+   if (intel->always_flush_cache) {
       intel_batchbuffer_emit_mi_flush(batch);
       used = batch->ptr - batch->map;
    }
@@ -244,14 +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");
@@ -293,11 +263,10 @@
 
 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;
 }
@@ -314,7 +283,7 @@
    struct intel_context *intel = batch->intel;
 
    if (intel->gen >= 4) {
-      BEGIN_BATCH(4, IGNORE_CLIPRECTS);
+      BEGIN_BATCH(4);
       OUT_BATCH(_3DSTATE_PIPE_CONTROL |
 		PIPE_CONTROL_INSTRUCTION_FLUSH |
 		PIPE_CONTROL_WRITE_FLUSH |
@@ -324,7 +293,7 @@
       OUT_BATCH(0); /* write data */
       ADVANCE_BATCH();
    } else {
-      BEGIN_BATCH(1, IGNORE_CLIPRECTS);
+      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 d4a9445..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 */
@@ -85,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);
@@ -121,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;			\
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index 9f638b0..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;
@@ -499,10 +364,11 @@
 		  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],
@@ -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_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
index 0564318..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;
 }
 
 
@@ -202,7 +184,6 @@
        || (fb->_NumColorDrawBuffers == 0)) {
       /* writing to 0  */
       colorRegions[0] = NULL;
-      intel->constant_cliprect = GL_TRUE;
    }
    else if (fb->_NumColorDrawBuffers > 1) {
        int i;
@@ -212,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;
       }
    }
 
@@ -291,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 f682ee3..956f233 100644
--- a/src/mesa/drivers/dri/intel/intel_clear.c
+++ b/src/mesa/drivers/dri/intel/intel_clear.c
@@ -68,7 +68,7 @@
 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;
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 26ff11b..13a28f0 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,7 +66,7 @@
 #endif
 
 
-#define DRIVER_DATE                     "20091221 2009Q4"
+#define DRIVER_DATE                     "20091221 DEVELOPMENT"
 #define DRIVER_DATE_GEM                 "GEM " DRIVER_DATE
 
 
@@ -176,9 +174,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 +191,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 +211,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 +250,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 +289,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 +361,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;
 
@@ -393,9 +389,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 +407,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;
 }
@@ -480,13 +472,6 @@
    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 +577,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,20 +596,28 @@
    driContextPriv->driverPrivate = intel;
    intel->intelScreen = intelScreen;
    intel->driScreen = sPriv;
-   intel->sarea = intelScreen->sarea;
    intel->driContext = driContextPriv;
-
-   if (IS_965(intel->intelScreen->deviceID))
-      intel->gen = 4;
-   else if (IS_9XX(intel->intelScreen->deviceID))
-      intel->gen = 3;
-   else
-      intel->gen = 2;
-
-   /* 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,
@@ -635,18 +628,14 @@
       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
@@ -732,14 +721,6 @@
 
    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 (intel->gen >= 4 && !intel->intelScreen->irq_active) {
       _mesa_printf("IRQs not active.  Exiting\n");
       exit(1);
@@ -751,9 +732,6 @@
    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);
@@ -802,7 +780,7 @@
 }
 
 void
-intelDestroyContext(__DRIcontextPrivate * driContextPriv)
+intelDestroyContext(__DRIcontext * driContextPriv)
 {
    struct intel_context *intel =
       (struct intel_context *) driContextPriv->driverPrivate;
@@ -849,57 +827,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 */
@@ -911,7 +838,7 @@
 }
 
 GLboolean
-intelUnbindContext(__DRIcontextPrivate * driContextPriv)
+intelUnbindContext(__DRIcontext * driContextPriv)
 {
    struct intel_context *intel =
       (struct intel_context *) driContextPriv->driverPrivate;
@@ -925,11 +852,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);
 
@@ -947,41 +873,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);
@@ -990,37 +887,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);
@@ -1028,143 +898,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 1afec09..c7b7235 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -135,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,
@@ -184,16 +176,13 @@
     * Generation number of the hardware: 2 is 8xx, 3 is 9xx pre-965, 4 is 965.
     */
    int gen;
+   GLboolean needs_ff_sync;
+   GLboolean is_ironlake;
+   GLboolean is_g4x;
+   GLboolean is_945;
+   GLboolean has_luminance_srgb;
 
-   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.
-    */
-   GLboolean ttm;
+   int urb_size;
 
    struct intel_batchbuffer *batch;
    drm_intel_bo *first_post_swapbuffers_batch;
@@ -217,10 +206,6 @@
    char *prevLockFile;
    int prevLockLine;
 
-   GLuint ClearColor565;
-   GLuint ClearColor8888;
-
-
    /* Offsets of fields within the current vertex:
     */
    GLuint coloroffset;
@@ -237,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;
 
@@ -262,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
@@ -302,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;
 
 
@@ -374,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 ???
@@ -481,12 +406,10 @@
 
 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);
 
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 48cdae5..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 },
@@ -175,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 }
@@ -201,14 +196,10 @@
     */
    driInitExtensions(ctx, card_extensions, GL_FALSE);
 
-   if (intel->ttm)
-      driInitExtensions(ctx, ttm_extensions, GL_FALSE);
-
-   if (IS_965(intel->intelScreen->deviceID))
+   if (intel->gen >= 4)
       driInitExtensions(ctx, brw_extensions, GL_FALSE);
 
-   if (IS_915(intel->intelScreen->deviceID)
-       || IS_945(intel->intelScreen->deviceID)) {
+   if (intel->gen == 3) {
       driInitExtensions(ctx, i915_extensions, GL_FALSE);
 
       if (driQueryOptionb(&intel->optionCache, "fragment_shader"))
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 608f75b..d58ffd9 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -222,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);
@@ -233,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)) {
@@ -398,8 +398,6 @@
 intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, 
 		     struct gl_texture_image *texImage)
 {
-   gl_format texFormat;
-
    if (texImage->TexFormat == MESA_FORMAT_ARGB8888) {
       irb->Base.DataType = GL_UNSIGNED_BYTE;
       DBG("Render to RGBA8 texture OK\n");
@@ -429,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;
@@ -594,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++) {
@@ -609,6 +616,7 @@
 	 continue;
 
       if (irb == NULL) {
+	 DBG("software rendering renderbuffer\n");
 	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
 	 continue;
       }
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h
index fa43077..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,8 +41,6 @@
    struct gl_renderbuffer Base;
    struct intel_region *region;
 
-   GLuint vbl_pending;   /**< vblank sequence number of pending flip */
-
    uint8_t *span_cache;
    unsigned long span_cache_offset;
 };
@@ -121,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 abb3024..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);
@@ -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;
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 19ca515..85e5ad2 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
@@ -229,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;
@@ -326,7 +323,6 @@
       }
    }
 out:
-   UNLOCK_HARDWARE(intel);
 
    if (INTEL_DEBUG & DEBUG_SYNC)
       intel_batchbuffer_flush(intel->batch);
@@ -505,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 622aaa2..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,11 @@
 				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);
 
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 20424e2..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__);
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 8097516..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,125 +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 (intel->gen >= 4 && 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..5165716 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,
@@ -239,17 +115,13 @@
 
 static const __DRIextension *intelScreenExtensions[] = {
     &driReadDrawableExtension,
-    &driCopySubBufferExtension.base,
-    &driSwapControlExtension.base,
-    &driFrameTrackingExtension.base,
-    &driMediaStreamCounterExtension.base,
     &intelTexOffsetExtension.base,
     &intelTexBufferExtension.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 +138,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 +155,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 +169,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 +184,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 +198,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 +275,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,69 +301,12 @@
 
 /**
  * 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];
@@ -842,19 +415,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 34c3d9d..605734d 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -517,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) {
@@ -553,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);
 }
 
 
@@ -613,15 +610,7 @@
 			 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->Base.Format) {
@@ -667,6 +656,9 @@
       return;
    }
 
+   /* 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) {
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_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index ef5aed3..d8e7109 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -110,7 +110,6 @@
    }
 
    /* intelFlush(ctx); */
-   LOCK_HARDWARE(intel);
    {
       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;
 
@@ -170,13 +168,10 @@
 			     image_x + dstx, image_y + dsty,
 			     width, height,
 			     GL_COPY)) {
-	 UNLOCK_HARDWARE(intel);
 	 return GL_FALSE;
       }
    }
 
-   UNLOCK_HARDWARE(intel);
-
    return GL_TRUE;
 }
 
diff --git a/src/mesa/drivers/dri/intel/intel_tex_format.c b/src/mesa/drivers/dri/intel/intel_tex_format.c
index 87efb72..a7c6c45 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_format.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_format.c
@@ -173,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 66d61f9..307669f 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -235,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);
 
@@ -245,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;
 }
@@ -469,8 +466,6 @@
 					   pixels, unpack, "glTexImage");
    }
 
-   LOCK_HARDWARE(intel);
-
    if (intelImage->mt) {
       if (pixels != NULL) {
 	 /* Flush any queued rendering with the texture before mapping. */
@@ -551,8 +546,6 @@
          intel_miptree_image_unmap(intel, intelImage->mt);
       texImage->Data = NULL;
    }
-
-   UNLOCK_HARDWARE(intel);
 }
 
 
@@ -732,7 +725,7 @@
 		   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;
@@ -751,7 +744,7 @@
 
    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.
     */
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/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_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/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 82d825b..86d4717 100644
--- a/src/mesa/drivers/dri/r128/r128_tris.c
+++ b/src/mesa/drivers/dri/r128/r128_tris.c
@@ -651,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/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 5f985d6..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;
@@ -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 6d99c03..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;
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_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c
index a417721..5b87ba6 100644
--- a/src/mesa/drivers/dri/r200/r200_tex.c
+++ b/src/mesa/drivers/dri/r200/r200_tex.c
@@ -378,7 +378,7 @@
       break;
 
    case GL_TEXTURE_BORDER_COLOR:
-      r200SetTexBorderColor( t, texObj->BorderColor );
+      r200SetTexBorderColor( t, texObj->BorderColor.f );
       break;
 
    case GL_TEXTURE_BASE_LEVEL:
@@ -470,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 7782404..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);
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index f87a6dd..be005bd 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -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/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 41ea23e..272f907 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
@@ -229,7 +229,8 @@
 /**
  * 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;
@@ -279,13 +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);
 
+	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.h b/src/mesa/drivers/dri/r300/compiler/radeon_program.h
index 0359288..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;
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..ea626d9
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/r300_blit.c
@@ -0,0 +1,607 @@
+/*
+ * 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_S8_Z24:
+        case MESA_FORMAT_X8_Z24:
+        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:
+            assert(!"Invalid format for US output\n");
+            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)
+{
+    /* 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_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);
+    }
+
+    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 ad8db6e..e1c33bb 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -45,7 +45,6 @@
 #include "radeon_drm.h"
 
 #include "r300_context.h"
-#include "r300_ioctl.h"
 #include "r300_reg.h"
 #include "r300_cmdbuf.h"
 #include "r300_emit.h"
@@ -72,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;
@@ -86,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)
@@ -256,110 +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:
-		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:
-		_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);
     }
 }
 
@@ -455,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);
@@ -467,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);
@@ -644,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);
@@ -694,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);
@@ -758,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);
@@ -779,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);
@@ -800,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 5f07b95..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* */
@@ -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_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_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 4ae593c..02c9425 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -68,7 +68,6 @@
 #include "tnl/tnl.h"
 #include "tnl/t_vp_build.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 726b3ff..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,7 +215,7 @@
 		break;
 
 	case GL_TEXTURE_BORDER_COLOR:
-		r300SetTexBorderColor(t, texObj->BorderColor);
+		r300SetTexBorderColor(t, texObj->BorderColor.f);
 		break;
 
 	case GL_TEXTURE_BASE_LEVEL:
@@ -308,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 bbe8b1e..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,67 +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(XRGB8888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
-	_ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
-	_ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
-	_ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
-	_ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
-	_ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
-	_ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
-	_ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
-	_ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
-	_ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
-	_ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
-	_ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
-	_ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
-	_ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
-	_ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
-	_ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
-	_ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
-	_ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
-	_ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
-	_ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
-	_ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
-	_ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
-	_ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
-	_ASSIGN(RGB_FLOAT32, 0xffffffff),
-	_ASSIGN(RGB_FLOAT16, 0xffffffff),
-	_ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
-	_ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
-	_ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
-	_ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
-	_ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
-	_ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
-	_ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
-	_ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
-	_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] = {
@@ -205,19 +248,18 @@
 	const struct gl_texture_image *firstImage;
 	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)
@@ -357,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;
 	}
@@ -409,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 */
@@ -458,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/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 94662ab..a1b4af7 100644
--- a/src/mesa/drivers/dri/r600/r600_context.h
+++ b/src/mesa/drivers/dri/r600/r600_context.h
@@ -154,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_tex.c b/src/mesa/drivers/dri/r600/r600_tex.c
index 9d83a64..f745fe3 100644
--- a/src/mesa/drivers/dri/r600/r600_tex.c
+++ b/src/mesa/drivers/dri/r600/r600_tex.c
@@ -305,7 +305,7 @@
 		break;
 
 	case GL_TEXTURE_BORDER_COLOR:
-		r600SetTexBorderColor(t, texObj->BorderColor);
+		r600SetTexBorderColor(t, texObj->BorderColor.f);
 		break;
 
 	case GL_TEXTURE_BASE_LEVEL:
@@ -391,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 fb5abdc..b8466bd 100644
--- a/src/mesa/drivers/dri/r600/r600_texstate.c
+++ b/src/mesa/drivers/dri/r600/r600_texstate.c
@@ -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;
@@ -713,6 +738,15 @@
 		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);
+	}
+
 }
 
 /**
@@ -919,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 */
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c
index b0b3892..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)
 {
@@ -999,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) )
@@ -1010,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) )
@@ -1043,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) )
@@ -1054,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) )
@@ -1065,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) )
@@ -1165,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);
@@ -1175,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)
             {
@@ -1191,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;
         }
     } 
@@ -1247,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;
 }
 
@@ -1306,6 +1422,7 @@
     else
     {
     switch (pILInst->SrcReg[0].File) {
+        case PROGRAM_UNIFORM: 
         case PROGRAM_CONSTANT:
         case PROGRAM_LOCAL_PARAM:
         case PROGRAM_ENV_PARAM:
@@ -1318,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;
         }
     }
 
@@ -1392,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) {
@@ -1412,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
@@ -1529,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",
@@ -1618,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) )
          ) ) 
@@ -1648,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;
 
@@ -1658,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, 
@@ -1935,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++) 
     {
@@ -2024,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++) 
     {
@@ -2057,7 +2224,7 @@
         if( is_gpr(sel) ) 
         {
             if( GL_FALSE == cycle_for_vector_bank_swizzle(bank_swizzle, src, &cycle) )
-            {
+            {             
                 return GL_FALSE;
             }
 
@@ -2069,7 +2236,7 @@
             else 
             {
                 if( GL_FALSE == reserve_gpr(pAsm, sel, chan, cycle) )
-                {
+                {                    
                     return GL_FALSE;
                 }
             }
@@ -2081,7 +2248,7 @@
             if( is_cfile(sel) ) 
             {        
                 if( GL_FALSE == reserve_cfile(pAsm, sel, chan) )
-                {
+                {                    
                     return GL_FALSE;
                 }
             }
@@ -2093,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;
@@ -2101,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];
@@ -2158,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;
@@ -2184,7 +2376,7 @@
                                          current_source_index,
                                          pcurrent_source, 
                                          scalar_channel_index) )     
-        {
+        {            
             return GL_FALSE;
         }
    
@@ -2198,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) )
@@ -2216,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) || 
@@ -2227,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;
         }
@@ -2257,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) 
         {            
@@ -2284,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;
@@ -2313,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;
@@ -2341,7 +2541,7 @@
         }
 
         if(GL_FALSE == add_alu_instruction(pAsm, alu_instruction_ptr, contiguous_slots_needed) )
-        {
+        {            
             return GL_FALSE;
         }
 
@@ -2352,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;
@@ -2415,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;
 }
 
@@ -2652,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)
@@ -2922,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;
@@ -2941,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;
 }
@@ -3019,6 +3272,7 @@
     {
         return GL_FALSE;
     }
+
     if( GL_FALSE == assemble_src(pAsm, 2, -1) ) 
     {
         return GL_FALSE;
@@ -3754,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;
 }
@@ -3907,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:
@@ -4004,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;
@@ -4034,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;
@@ -4057,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);
 
@@ -4105,14 +4384,27 @@
 
     }
 
-    if(pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_TXB)
+    switch(pAsm->pILInst[pAsm->uiCurInst].Opcode)
     {
-        pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE_L;
+        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;
     }
-    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 )
@@ -4120,7 +4412,7 @@
         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.
@@ -4154,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;
 }
 
@@ -4277,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: 
@@ -4325,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;  
 
@@ -4354,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;  
@@ -4365,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: 
@@ -4405,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: 
@@ -4420,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) ) 
@@ -4461,7 +5748,8 @@
                 }
             }
             break;
-
+        case OPCODE_DDX:
+        case OPCODE_DDY:
         case OPCODE_TEX: 
         case OPCODE_TXB:  
         case OPCODE_TXP: 
@@ -4469,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
@@ -4509,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,
@@ -4803,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) 
@@ -4837,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 ee12582..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);
@@ -447,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,
@@ -468,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);
@@ -482,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);
@@ -495,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,
@@ -515,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 7f1894d..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,7 +55,7 @@
 	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) {
@@ -68,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);
@@ -92,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);
@@ -443,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)
@@ -1306,8 +1341,8 @@
 	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 ccafd43..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);
@@ -394,6 +607,13 @@
              EXPORT_MODE_shift, EXPORT_MODE_mask);
 
     // 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)
     {
@@ -407,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);
@@ -420,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);
@@ -433,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);
@@ -448,17 +668,67 @@
 
     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);
+		    }
 	    }
     }
 
+    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);
     if (r700->CB_SHADER_CONTROL.u32All != ((1 << exportCount) - 1))
     {
@@ -469,7 +739,8 @@
     /* 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)
@@ -482,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 47f89c9..eab27cb 100644
--- a/src/mesa/drivers/dri/r600/r700_render.c
+++ b/src/mesa/drivers/dri/r600/r700_render.c
@@ -526,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);
@@ -559,6 +562,8 @@
             break;
     }
 
+    radeon_bo_unmap(attr->bo);
+
     if (mapped_named_bo) 
     {
         ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
@@ -577,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);
@@ -596,6 +603,7 @@
         }
     }
 
+    radeon_bo_unmap(attr->bo);
     if (mapped_named_bo) 
     {
         ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
@@ -664,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); 
@@ -686,6 +698,7 @@
                     assert(0); 
                     break;
                 }
+		radeon_bo_unmap(context->stream_desc[index].bo);
             }
         }
 
@@ -757,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);
 
@@ -770,6 +784,7 @@
             *out++ = in[i];
         }
 
+	radeon_bo_unmap(context->ind_buf.bo);
 #if MESA_BIG_ENDIAN
     }
     else
@@ -780,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);
 
@@ -792,6 +808,7 @@
         {
             *out++ = in[i];
         }
+	radeon_bo_unmap(context->ind_buf.bo);
 #endif
     }
 
@@ -837,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;
 
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 16b05d5..3c8cb57 100644
--- a/src/mesa/drivers/dri/r600/r700_state.c
+++ b/src/mesa/drivers/dri/r600/r700_state.c
@@ -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;
@@ -1071,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;
@@ -1724,10 +1724,10 @@
     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);
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c
index 4ca5ce6..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);
 }
 
@@ -236,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;
 }
 
@@ -326,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)) )
 	{
@@ -338,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);
 
@@ -616,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)
@@ -628,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/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 9b64c21..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;
@@ -428,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;
@@ -496,7 +496,7 @@
 	UNLOCK_HARDWARE( rmesa );
 }
 
-static int radeonScheduleSwap(__DRIdrawablePrivate *dPriv, GLboolean *missed_target)
+static int radeonScheduleSwap(__DRIdrawable *dPriv, GLboolean *missed_target)
 {
 	radeonContextPtr rmesa;
 
@@ -519,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;
 
@@ -571,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;
@@ -615,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) {
@@ -641,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);
@@ -817,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);
       }
 	}
 
@@ -834,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 */
@@ -885,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;
@@ -1095,7 +1116,7 @@
 	   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 );
@@ -1103,12 +1124,13 @@
 	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
@@ -1208,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 0608fe2..f31f08e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common.h
@@ -13,10 +13,10 @@
 
 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);
@@ -42,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 71f70d7..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;
@@ -291,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;
@@ -355,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;
 
@@ -499,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;
@@ -525,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]) {
@@ -533,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,
@@ -562,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,
@@ -715,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;
@@ -735,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 6298748..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
@@ -328,6 +328,7 @@
 	GLuint vertex_attr_count;
 
 	GLuint emit_prediction;
+        struct radeon_bo *bo;
 };
 
 #define RADEON_MAX_AOS_ARRAYS		16
@@ -380,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;
@@ -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 12ab33a..dfedc38 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_context.h
@@ -451,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_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c
index 232972d..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);
 	}
@@ -361,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 */
@@ -397,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;
 
@@ -416,6 +409,8 @@
 	    }
 	    rmesa->swtcl.numverts = 0;
 	}
+	radeon_bo_unref(rmesa->swtcl.bo);
+	rmesa->swtcl.bo = NULL;
 }
 /* Alloc space in the current dma region.
  */
@@ -426,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) {
@@ -449,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 fc21069..7b1f84a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -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;
 
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 7ad781b..9dee691 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.c
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.c
@@ -58,9 +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;
+	__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);
 
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 d7b5d71..033f26d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -68,6 +68,19 @@
 	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);
+}
+
 /**
  * Compute sizes and fill in offset and blit information for the given
  * image (determined by \p face and \p level).
@@ -80,25 +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 (_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, lvl->height);
+		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 = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
-		lvl->size = lvl->rowstride * lvl->height;
+		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 = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) * 2 + 31) & ~31;
-		lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth;
+		lvl->size = lvl->rowstride * ((height + 1) / 2) * lvl->depth;
 	} else {
 		row_align = rmesa->texture_row_align - 1;
 		lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
-		lvl->size = lvl->rowstride * lvl->height * lvl->depth;
+		lvl->size = lvl->rowstride * height * lvl->depth;
 	}
 	assert(lvl->size > 0);
 
@@ -110,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)
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index be2d836..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 )
 {
@@ -911,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;
@@ -1250,7 +1250,7 @@
 }
 
 static radeonScreenPtr
-radeonCreateScreen2(__DRIscreenPrivate *sPriv)
+radeonCreateScreen2(__DRIscreen *sPriv)
 {
    radeonScreenPtr screen;
    int i;
@@ -1401,7 +1401,7 @@
 /* Destroy the device specific screen private data struct.
  */
 static void
-radeonDestroyScreen( __DRIscreenPrivate *sPriv )
+radeonDestroyScreen( __DRIscreen *sPriv )
 {
     radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
 
@@ -1435,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 );
@@ -1459,8 +1459,8 @@
  * pbuffers.
  */
 static GLboolean
-radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
-                    __DRIdrawablePrivate *driDrawPriv,
+radeonCreateBuffer( __DRIscreen *driScrnPriv,
+                    __DRIdrawable *driDrawPriv,
                     const __GLcontextModes *mesaVis,
                     GLboolean isPixmap )
 {
@@ -1559,7 +1559,7 @@
 }
 
 void
-radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+radeonDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
     struct radeon_framebuffer *rfb;
     if (!driDrawPriv)
@@ -1581,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";
@@ -1631,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];
@@ -1698,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;
 
@@ -1751,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 665f2b6..8db3d2b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -827,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
@@ -854,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)
@@ -887,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)
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index f6c733a..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 );
@@ -1400,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;
@@ -1455,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_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_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c
index 749ab75..14163f1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tex.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tex.c
@@ -341,7 +341,7 @@
       break;
 
    case GL_TEXTURE_BORDER_COLOR:
-      radeonSetTexBorderColor( t, texObj->BorderColor );
+      radeonSetTexBorderColor( t, texObj->BorderColor.f );
       break;
 
    case GL_TEXTURE_BASE_LEVEL:
@@ -428,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 3cbe3b4..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);
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 77ab8d1..d0b64e8 100644
--- a/src/mesa/drivers/dri/savage/savageioctl.c
+++ b/src/mesa/drivers/dri/savage/savageioctl.c
@@ -360,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;
    }
 
@@ -433,7 +433,7 @@
 /*
  * Copy the back buffer to the front buffer. 
  */
-void savageSwapBuffers( __DRIdrawablePrivate *dPriv )
+void savageSwapBuffers( __DRIdrawable *dPriv )
 {
    savageContextPtr imesa;
 
@@ -537,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 0714101..9a92541 100644
--- a/src/mesa/drivers/dri/savage/savagetris.c
+++ b/src/mesa/drivers/dri/savage/savagetris.c
@@ -880,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 */
@@ -977,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
@@ -1026,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 );
@@ -1036,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_context.c b/src/mesa/drivers/dri/sis/sis_context.c
index 346e8c5..0944f4d 100644
--- a/src/mesa/drivers/dri/sis/sis_context.c
+++ b/src/mesa/drivers/dri/sis/sis_context.c
@@ -162,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;
@@ -339,7 +339,7 @@
 }
 
 void
-sisDestroyContext ( __DRIcontextPrivate *driContextPriv )
+sisDestroyContext ( __DRIcontext *driContextPriv )
 {
    sisContextPtr smesa = (sisContextPtr)driContextPriv->driverPrivate;
 
@@ -367,9 +367,9 @@
 }
 
 GLboolean
-sisMakeCurrent( __DRIcontextPrivate *driContextPriv,
-                __DRIdrawablePrivate *driDrawPriv,
-                __DRIdrawablePrivate *driReadPriv )
+sisMakeCurrent( __DRIcontext *driContextPriv,
+                __DRIdrawable *driDrawPriv,
+                __DRIdrawable *driReadPriv )
 {
    if ( driContextPriv ) {
       GET_CURRENT_CONTEXT(ctx);
@@ -398,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 4fa2e41..4690274 100644
--- a/src/mesa/drivers/dri/sis/sis_tris.c
+++ b/src/mesa/drivers/dri/sis/sis_tris.c
@@ -904,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/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_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_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 91c94fa..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 &&
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 e2f1f02..01359d5 100644
--- a/src/mesa/drivers/dri/unichrome/via_tris.c
+++ b/src/mesa/drivers/dri/unichrome/via_tris.c
@@ -833,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/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/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/Makefile b/src/mesa/glapi/Makefile
index 71bef68..4db0ff1 100644
--- a/src/mesa/glapi/Makefile
+++ b/src/mesa/glapi/Makefile
@@ -56,10 +56,12 @@
 	ARB_sync.xml \
 	ARB_vertex_array_object.xml \
 	APPLE_vertex_array_object.xml \
+	EXT_draw_buffers2.xml \
 	EXT_framebuffer_object.xml \
 	EXT_packed_depth_stencil.xml \
 	EXT_provoking_vertex.xml \
-	EXT_texture_array.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 34c7746..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. -->
 
@@ -12242,6 +12244,9 @@
 
 <xi:include href="EXT_provoking_vertex.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
+<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">
         <size name="GetBufferParameteriv" mode="get"/>
diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c
index e36fccb..84e5a82 100644
--- a/src/mesa/glapi/glapi.c
+++ b/src/mesa/glapi/glapi.c
@@ -73,7 +73,6 @@
 #include "glapioffsets.h"
 #include "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 "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 ed443c1..1401c1c 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 319a4ab..96b2ac7 100644
--- a/src/mesa/glapi/glapitemp.h
+++ b/src/mesa/glapi/glapitemp.h
@@ -5677,6 +5677,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));
@@ -5687,51 +5727,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));
 }
@@ -6537,14 +6577,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.
diff --git a/src/mesa/glapi/glprocs.h b/src/mesa/glapi/glprocs.h
index 1ad7e84..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"
@@ -1196,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 */
 
 
@@ -1250,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[] = {
@@ -2047,316 +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, glRenderbufferStorageMultisample, glRenderbufferStorageMultisample, NULL, _gloffset_RenderbufferStorageMultisample),
-    NAME_FUNC_OFFSET(17991, gl_dispatch_stub_584, gl_dispatch_stub_584, NULL, _gloffset_SampleMaskSGIS),
-    NAME_FUNC_OFFSET(18007, gl_dispatch_stub_585, gl_dispatch_stub_585, NULL, _gloffset_SamplePatternSGIS),
-    NAME_FUNC_OFFSET(18026, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET(18044, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET(18065, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET(18087, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET(18106, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET(18128, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET(18151, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
-    NAME_FUNC_OFFSET(18170, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
-    NAME_FUNC_OFFSET(18190, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
-    NAME_FUNC_OFFSET(18209, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
-    NAME_FUNC_OFFSET(18229, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
-    NAME_FUNC_OFFSET(18248, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
-    NAME_FUNC_OFFSET(18268, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
-    NAME_FUNC_OFFSET(18287, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
-    NAME_FUNC_OFFSET(18307, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
-    NAME_FUNC_OFFSET(18326, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
-    NAME_FUNC_OFFSET(18346, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
-    NAME_FUNC_OFFSET(18366, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
-    NAME_FUNC_OFFSET(18387, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
-    NAME_FUNC_OFFSET(18407, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
-    NAME_FUNC_OFFSET(18428, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
-    NAME_FUNC_OFFSET(18448, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
-    NAME_FUNC_OFFSET(18469, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
-    NAME_FUNC_OFFSET(18493, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
-    NAME_FUNC_OFFSET(18511, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
-    NAME_FUNC_OFFSET(18531, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
-    NAME_FUNC_OFFSET(18549, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
-    NAME_FUNC_OFFSET(18561, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
-    NAME_FUNC_OFFSET(18574, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
-    NAME_FUNC_OFFSET(18586, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
-    NAME_FUNC_OFFSET(18599, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
-    NAME_FUNC_OFFSET(18619, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
-    NAME_FUNC_OFFSET(18643, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
-    NAME_FUNC_OFFSET(18657, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
-    NAME_FUNC_OFFSET(18674, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
-    NAME_FUNC_OFFSET(18689, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
-    NAME_FUNC_OFFSET(18707, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
-    NAME_FUNC_OFFSET(18721, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
-    NAME_FUNC_OFFSET(18738, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
-    NAME_FUNC_OFFSET(18753, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
-    NAME_FUNC_OFFSET(18771, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
-    NAME_FUNC_OFFSET(18785, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
-    NAME_FUNC_OFFSET(18802, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
-    NAME_FUNC_OFFSET(18817, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
-    NAME_FUNC_OFFSET(18835, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
-    NAME_FUNC_OFFSET(18849, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
-    NAME_FUNC_OFFSET(18866, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
-    NAME_FUNC_OFFSET(18881, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
-    NAME_FUNC_OFFSET(18899, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
-    NAME_FUNC_OFFSET(18913, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
-    NAME_FUNC_OFFSET(18930, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
-    NAME_FUNC_OFFSET(18945, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
-    NAME_FUNC_OFFSET(18963, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
-    NAME_FUNC_OFFSET(18977, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
-    NAME_FUNC_OFFSET(18994, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
-    NAME_FUNC_OFFSET(19009, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
-    NAME_FUNC_OFFSET(19027, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
-    NAME_FUNC_OFFSET(19041, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
-    NAME_FUNC_OFFSET(19058, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
-    NAME_FUNC_OFFSET(19073, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
-    NAME_FUNC_OFFSET(19091, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
-    NAME_FUNC_OFFSET(19105, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
-    NAME_FUNC_OFFSET(19122, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
-    NAME_FUNC_OFFSET(19137, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
-    NAME_FUNC_OFFSET(19155, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
-    NAME_FUNC_OFFSET(19172, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
-    NAME_FUNC_OFFSET(19192, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
-    NAME_FUNC_OFFSET(19209, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
-    NAME_FUNC_OFFSET(19235, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
-    NAME_FUNC_OFFSET(19264, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
-    NAME_FUNC_OFFSET(19279, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
-    NAME_FUNC_OFFSET(19297, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
-    NAME_FUNC_OFFSET(19316, gl_dispatch_stub_755, gl_dispatch_stub_755, NULL, _gloffset_DeleteVertexArraysAPPLE),
-    NAME_FUNC_OFFSET(19337, gl_dispatch_stub_757, gl_dispatch_stub_757, NULL, _gloffset_IsVertexArrayAPPLE),
-    NAME_FUNC_OFFSET(19353, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_BlendEquationSeparateEXT),
-    NAME_FUNC_OFFSET(19377, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_BlendEquationSeparateEXT),
-    NAME_FUNC_OFFSET(19404, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
-    NAME_FUNC_OFFSET(19422, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
-    NAME_FUNC_OFFSET(19441, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
-    NAME_FUNC_OFFSET(19466, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
-    NAME_FUNC_OFFSET(19487, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
-    NAME_FUNC_OFFSET(19509, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
-    NAME_FUNC_OFFSET(19535, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
-    NAME_FUNC_OFFSET(19558, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
-    NAME_FUNC_OFFSET(19581, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
-    NAME_FUNC_OFFSET(19604, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
-    NAME_FUNC_OFFSET(19622, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
-    NAME_FUNC_OFFSET(19641, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
-    NAME_FUNC_OFFSET(19658, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
-    NAME_FUNC_OFFSET(19696, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
-    NAME_FUNC_OFFSET(19725, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
-    NAME_FUNC_OFFSET(19741, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
-    NAME_FUNC_OFFSET(19758, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
-    NAME_FUNC_OFFSET(19780, gl_dispatch_stub_783, gl_dispatch_stub_783, NULL, _gloffset_BlitFramebufferEXT),
-    NAME_FUNC_OFFSET(19798, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
-    NAME_FUNC_OFFSET(19824, 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 737fd4d..f480edf 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 a14f71c..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,
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/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/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 c504897..2eac1cc 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -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 87eae96..320c590 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -571,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
 
@@ -1014,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);
@@ -1373,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 27ed921..e99e87d 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 */
@@ -766,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 );
@@ -787,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,
@@ -1018,6 +1016,11 @@
 			  GLbitfield, GLuint64);
    /*@}*/
 #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);
 };
 
 
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/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 8a39401..2273138 100644
--- a/src/mesa/main/enums.c
+++ b/src/mesa/main/enums.c
@@ -1326,12 +1326,16 @@
    "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"
@@ -1918,7 +1922,7 @@
    "GL_ZOOM_Y\0"
    ;
 
-static const enum_elt all_enums[1880] =
+static const enum_elt all_enums[1884] =
 {
    {     0, 0x00000600 }, /* GL_2D */
    {     6, 0x00001407 }, /* GL_2_BYTES */
@@ -3210,607 +3214,611 @@
    { 28419, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
    { 28467, 0x00008614 }, /* GL_QUAD_MESH_SUN */
    { 28484, 0x00000008 }, /* GL_QUAD_STRIP */
-   { 28498, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
-   { 28520, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */
-   { 28546, 0x00008866 }, /* GL_QUERY_RESULT */
-   { 28562, 0x00008866 }, /* GL_QUERY_RESULT_ARB */
-   { 28582, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
-   { 28608, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */
-   { 28638, 0x00002002 }, /* GL_R */
-   { 28643, 0x00002A10 }, /* GL_R3_G3_B2 */
-   { 28655, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
-   { 28688, 0x00000C02 }, /* GL_READ_BUFFER */
-   { 28703, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */
-   { 28723, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING */
-   { 28751, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
-   { 28783, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */
-   { 28807, 0x000088B8 }, /* GL_READ_ONLY */
-   { 28820, 0x000088B8 }, /* GL_READ_ONLY_ARB */
-   { 28837, 0x000088BA }, /* GL_READ_WRITE */
-   { 28851, 0x000088BA }, /* GL_READ_WRITE_ARB */
-   { 28869, 0x00001903 }, /* GL_RED */
-   { 28876, 0x00008016 }, /* GL_REDUCE */
-   { 28886, 0x00008016 }, /* GL_REDUCE_EXT */
-   { 28900, 0x00000D15 }, /* GL_RED_BIAS */
-   { 28912, 0x00000D52 }, /* GL_RED_BITS */
-   { 28924, 0x00000D14 }, /* GL_RED_SCALE */
-   { 28937, 0x00008512 }, /* GL_REFLECTION_MAP */
-   { 28955, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */
-   { 28977, 0x00008512 }, /* GL_REFLECTION_MAP_NV */
-   { 28998, 0x00001C00 }, /* GL_RENDER */
-   { 29008, 0x00008D41 }, /* GL_RENDERBUFFER */
-   { 29024, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */
-   { 29051, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING */
-   { 29075, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */
-   { 29103, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */
-   { 29129, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */
-   { 29156, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */
-   { 29176, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */
-   { 29203, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */
-   { 29226, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */
-   { 29253, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
-   { 29285, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
-   { 29321, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */
-   { 29346, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */
-   { 29370, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES_EXT */
-   { 29398, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */
-   { 29427, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */
-   { 29449, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */
-   { 29475, 0x00001F01 }, /* GL_RENDERER */
-   { 29487, 0x00000C40 }, /* GL_RENDER_MODE */
-   { 29502, 0x00002901 }, /* GL_REPEAT */
-   { 29512, 0x00001E01 }, /* GL_REPLACE */
-   { 29523, 0x00008062 }, /* GL_REPLACE_EXT */
-   { 29538, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
-   { 29561, 0x0000803A }, /* GL_RESCALE_NORMAL */
-   { 29579, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */
-   { 29601, 0x00000102 }, /* GL_RETURN */
-   { 29611, 0x00001907 }, /* GL_RGB */
-   { 29618, 0x00008052 }, /* GL_RGB10 */
-   { 29627, 0x00008059 }, /* GL_RGB10_A2 */
-   { 29639, 0x00008059 }, /* GL_RGB10_A2_EXT */
-   { 29655, 0x00008052 }, /* GL_RGB10_EXT */
-   { 29668, 0x00008053 }, /* GL_RGB12 */
-   { 29677, 0x00008053 }, /* GL_RGB12_EXT */
-   { 29690, 0x00008054 }, /* GL_RGB16 */
-   { 29699, 0x00008054 }, /* GL_RGB16_EXT */
-   { 29712, 0x0000804E }, /* GL_RGB2_EXT */
-   { 29724, 0x0000804F }, /* GL_RGB4 */
-   { 29732, 0x0000804F }, /* GL_RGB4_EXT */
-   { 29744, 0x000083A1 }, /* GL_RGB4_S3TC */
-   { 29757, 0x00008050 }, /* GL_RGB5 */
-   { 29765, 0x00008057 }, /* GL_RGB5_A1 */
-   { 29776, 0x00008057 }, /* GL_RGB5_A1_EXT */
-   { 29791, 0x00008050 }, /* GL_RGB5_EXT */
-   { 29803, 0x00008051 }, /* GL_RGB8 */
-   { 29811, 0x00008051 }, /* GL_RGB8_EXT */
-   { 29823, 0x00001908 }, /* GL_RGBA */
-   { 29831, 0x0000805A }, /* GL_RGBA12 */
-   { 29841, 0x0000805A }, /* GL_RGBA12_EXT */
-   { 29855, 0x0000805B }, /* GL_RGBA16 */
-   { 29865, 0x0000805B }, /* GL_RGBA16_EXT */
-   { 29879, 0x00008055 }, /* GL_RGBA2 */
-   { 29888, 0x00008055 }, /* GL_RGBA2_EXT */
-   { 29901, 0x00008056 }, /* GL_RGBA4 */
-   { 29910, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
-   { 29929, 0x00008056 }, /* GL_RGBA4_EXT */
-   { 29942, 0x000083A3 }, /* GL_RGBA4_S3TC */
-   { 29956, 0x00008058 }, /* GL_RGBA8 */
-   { 29965, 0x00008058 }, /* GL_RGBA8_EXT */
-   { 29978, 0x00008F97 }, /* GL_RGBA8_SNORM */
-   { 29993, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
-   { 30011, 0x00000C31 }, /* GL_RGBA_MODE */
-   { 30024, 0x000083A2 }, /* GL_RGBA_S3TC */
-   { 30037, 0x00008F93 }, /* GL_RGBA_SNORM */
-   { 30051, 0x000083A0 }, /* GL_RGB_S3TC */
-   { 30063, 0x00008573 }, /* GL_RGB_SCALE */
-   { 30076, 0x00008573 }, /* GL_RGB_SCALE_ARB */
-   { 30093, 0x00008573 }, /* GL_RGB_SCALE_EXT */
-   { 30110, 0x00000407 }, /* GL_RIGHT */
-   { 30119, 0x00002000 }, /* GL_S */
-   { 30124, 0x00008B5D }, /* GL_SAMPLER_1D */
-   { 30138, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */
-   { 30159, 0x00008B5E }, /* GL_SAMPLER_2D */
-   { 30173, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */
-   { 30194, 0x00008B5F }, /* GL_SAMPLER_3D */
-   { 30208, 0x00008B60 }, /* GL_SAMPLER_CUBE */
-   { 30224, 0x000080A9 }, /* GL_SAMPLES */
-   { 30235, 0x000086B4 }, /* GL_SAMPLES_3DFX */
-   { 30251, 0x000080A9 }, /* GL_SAMPLES_ARB */
-   { 30266, 0x00008914 }, /* GL_SAMPLES_PASSED */
-   { 30284, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */
-   { 30306, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
-   { 30334, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */
-   { 30366, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
-   { 30389, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */
-   { 30416, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
-   { 30434, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
-   { 30457, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */
-   { 30479, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
-   { 30498, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */
-   { 30521, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
-   { 30547, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */
-   { 30577, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
-   { 30602, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */
-   { 30631, 0x00080000 }, /* GL_SCISSOR_BIT */
-   { 30646, 0x00000C10 }, /* GL_SCISSOR_BOX */
-   { 30661, 0x00000C11 }, /* GL_SCISSOR_TEST */
-   { 30677, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
-   { 30702, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
-   { 30742, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */
-   { 30786, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
-   { 30819, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
-   { 30849, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
-   { 30881, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
-   { 30911, 0x00001C02 }, /* GL_SELECT */
-   { 30921, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
-   { 30949, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
-   { 30974, 0x00008012 }, /* GL_SEPARABLE_2D */
-   { 30990, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
-   { 31017, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */
-   { 31048, 0x0000150F }, /* GL_SET */
-   { 31055, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
-   { 31076, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */
-   { 31100, 0x00008B4F }, /* GL_SHADER_TYPE */
-   { 31115, 0x00000B54 }, /* GL_SHADE_MODEL */
-   { 31130, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */
-   { 31158, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */
-   { 31181, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
-   { 31211, 0x00001601 }, /* GL_SHININESS */
-   { 31224, 0x00001402 }, /* GL_SHORT */
-   { 31233, 0x00009119 }, /* GL_SIGNALED */
-   { 31245, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */
-   { 31266, 0x000081F9 }, /* GL_SINGLE_COLOR */
-   { 31282, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */
-   { 31302, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
-   { 31321, 0x00008C46 }, /* GL_SLUMINANCE */
-   { 31335, 0x00008C47 }, /* GL_SLUMINANCE8 */
-   { 31350, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */
-   { 31372, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */
-   { 31392, 0x00001D01 }, /* GL_SMOOTH */
-   { 31402, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */
-   { 31435, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */
-   { 31462, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */
-   { 31495, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */
-   { 31522, 0x00008588 }, /* GL_SOURCE0_ALPHA */
-   { 31539, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */
-   { 31560, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */
-   { 31581, 0x00008580 }, /* GL_SOURCE0_RGB */
-   { 31596, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */
-   { 31615, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */
-   { 31634, 0x00008589 }, /* GL_SOURCE1_ALPHA */
-   { 31651, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */
-   { 31672, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */
-   { 31693, 0x00008581 }, /* GL_SOURCE1_RGB */
-   { 31708, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */
-   { 31727, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */
-   { 31746, 0x0000858A }, /* GL_SOURCE2_ALPHA */
-   { 31763, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */
-   { 31784, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */
-   { 31805, 0x00008582 }, /* GL_SOURCE2_RGB */
-   { 31820, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */
-   { 31839, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */
-   { 31858, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
-   { 31878, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
-   { 31896, 0x00001202 }, /* GL_SPECULAR */
-   { 31908, 0x00002402 }, /* GL_SPHERE_MAP */
-   { 31922, 0x00001206 }, /* GL_SPOT_CUTOFF */
-   { 31937, 0x00001204 }, /* GL_SPOT_DIRECTION */
-   { 31955, 0x00001205 }, /* GL_SPOT_EXPONENT */
-   { 31972, 0x00008588 }, /* GL_SRC0_ALPHA */
-   { 31986, 0x00008580 }, /* GL_SRC0_RGB */
-   { 31998, 0x00008589 }, /* GL_SRC1_ALPHA */
-   { 32012, 0x00008581 }, /* GL_SRC1_RGB */
-   { 32024, 0x0000858A }, /* GL_SRC2_ALPHA */
-   { 32038, 0x00008582 }, /* GL_SRC2_RGB */
-   { 32050, 0x00000302 }, /* GL_SRC_ALPHA */
-   { 32063, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
-   { 32085, 0x00000300 }, /* GL_SRC_COLOR */
-   { 32098, 0x00008C40 }, /* GL_SRGB */
-   { 32106, 0x00008C41 }, /* GL_SRGB8 */
-   { 32115, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */
-   { 32131, 0x00008C42 }, /* GL_SRGB_ALPHA */
-   { 32145, 0x00000503 }, /* GL_STACK_OVERFLOW */
-   { 32163, 0x00000504 }, /* GL_STACK_UNDERFLOW */
-   { 32182, 0x000088E6 }, /* GL_STATIC_COPY */
-   { 32197, 0x000088E6 }, /* GL_STATIC_COPY_ARB */
-   { 32216, 0x000088E4 }, /* GL_STATIC_DRAW */
-   { 32231, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */
-   { 32250, 0x000088E5 }, /* GL_STATIC_READ */
-   { 32265, 0x000088E5 }, /* GL_STATIC_READ_ARB */
-   { 32284, 0x00001802 }, /* GL_STENCIL */
-   { 32295, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */
-   { 32317, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */
-   { 32343, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */
-   { 32364, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */
-   { 32389, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */
-   { 32410, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */
-   { 32435, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
-   { 32467, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */
-   { 32503, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
-   { 32535, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */
-   { 32571, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */
-   { 32591, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */
-   { 32618, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */
-   { 32644, 0x00000D57 }, /* GL_STENCIL_BITS */
-   { 32660, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */
-   { 32682, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
-   { 32705, 0x00000B94 }, /* GL_STENCIL_FAIL */
-   { 32721, 0x00000B92 }, /* GL_STENCIL_FUNC */
-   { 32737, 0x00001901 }, /* GL_STENCIL_INDEX */
-   { 32754, 0x00008D46 }, /* GL_STENCIL_INDEX1 */
-   { 32772, 0x00008D49 }, /* GL_STENCIL_INDEX16 */
-   { 32791, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */
-   { 32814, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */
-   { 32836, 0x00008D47 }, /* GL_STENCIL_INDEX4 */
-   { 32854, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */
-   { 32876, 0x00008D48 }, /* GL_STENCIL_INDEX8 */
-   { 32894, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */
-   { 32916, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
-   { 32937, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
-   { 32964, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
-   { 32991, 0x00000B97 }, /* GL_STENCIL_REF */
-   { 33006, 0x00000B90 }, /* GL_STENCIL_TEST */
-   { 33022, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
-   { 33051, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
-   { 33073, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
-   { 33094, 0x00000C33 }, /* GL_STEREO */
-   { 33104, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */
-   { 33128, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */
-   { 33153, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */
-   { 33177, 0x000088E2 }, /* GL_STREAM_COPY */
-   { 33192, 0x000088E2 }, /* GL_STREAM_COPY_ARB */
-   { 33211, 0x000088E0 }, /* GL_STREAM_DRAW */
-   { 33226, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */
-   { 33245, 0x000088E1 }, /* GL_STREAM_READ */
-   { 33260, 0x000088E1 }, /* GL_STREAM_READ_ARB */
-   { 33279, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
-   { 33296, 0x000084E7 }, /* GL_SUBTRACT */
-   { 33308, 0x000084E7 }, /* GL_SUBTRACT_ARB */
-   { 33324, 0x00009113 }, /* GL_SYNC_CONDITION */
-   { 33342, 0x00009116 }, /* GL_SYNC_FENCE */
-   { 33356, 0x00009115 }, /* GL_SYNC_FLAGS */
-   { 33370, 0x00000001 }, /* GL_SYNC_FLUSH_COMMANDS_BIT */
-   { 33397, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
-   { 33427, 0x00009114 }, /* GL_SYNC_STATUS */
-   { 33442, 0x00002001 }, /* GL_T */
-   { 33447, 0x00002A2A }, /* GL_T2F_C3F_V3F */
-   { 33462, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
-   { 33481, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
-   { 33497, 0x00002A2B }, /* GL_T2F_N3F_V3F */
-   { 33512, 0x00002A27 }, /* GL_T2F_V3F */
-   { 33523, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
-   { 33542, 0x00002A28 }, /* GL_T4F_V4F */
-   { 33553, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
-   { 33576, 0x00001702 }, /* GL_TEXTURE */
-   { 33587, 0x000084C0 }, /* GL_TEXTURE0 */
-   { 33599, 0x000084C0 }, /* GL_TEXTURE0_ARB */
-   { 33615, 0x000084C1 }, /* GL_TEXTURE1 */
-   { 33627, 0x000084CA }, /* GL_TEXTURE10 */
-   { 33640, 0x000084CA }, /* GL_TEXTURE10_ARB */
-   { 33657, 0x000084CB }, /* GL_TEXTURE11 */
-   { 33670, 0x000084CB }, /* GL_TEXTURE11_ARB */
-   { 33687, 0x000084CC }, /* GL_TEXTURE12 */
-   { 33700, 0x000084CC }, /* GL_TEXTURE12_ARB */
-   { 33717, 0x000084CD }, /* GL_TEXTURE13 */
-   { 33730, 0x000084CD }, /* GL_TEXTURE13_ARB */
-   { 33747, 0x000084CE }, /* GL_TEXTURE14 */
-   { 33760, 0x000084CE }, /* GL_TEXTURE14_ARB */
-   { 33777, 0x000084CF }, /* GL_TEXTURE15 */
-   { 33790, 0x000084CF }, /* GL_TEXTURE15_ARB */
-   { 33807, 0x000084D0 }, /* GL_TEXTURE16 */
-   { 33820, 0x000084D0 }, /* GL_TEXTURE16_ARB */
-   { 33837, 0x000084D1 }, /* GL_TEXTURE17 */
-   { 33850, 0x000084D1 }, /* GL_TEXTURE17_ARB */
-   { 33867, 0x000084D2 }, /* GL_TEXTURE18 */
-   { 33880, 0x000084D2 }, /* GL_TEXTURE18_ARB */
-   { 33897, 0x000084D3 }, /* GL_TEXTURE19 */
-   { 33910, 0x000084D3 }, /* GL_TEXTURE19_ARB */
-   { 33927, 0x000084C1 }, /* GL_TEXTURE1_ARB */
-   { 33943, 0x000084C2 }, /* GL_TEXTURE2 */
-   { 33955, 0x000084D4 }, /* GL_TEXTURE20 */
-   { 33968, 0x000084D4 }, /* GL_TEXTURE20_ARB */
-   { 33985, 0x000084D5 }, /* GL_TEXTURE21 */
-   { 33998, 0x000084D5 }, /* GL_TEXTURE21_ARB */
-   { 34015, 0x000084D6 }, /* GL_TEXTURE22 */
-   { 34028, 0x000084D6 }, /* GL_TEXTURE22_ARB */
-   { 34045, 0x000084D7 }, /* GL_TEXTURE23 */
-   { 34058, 0x000084D7 }, /* GL_TEXTURE23_ARB */
-   { 34075, 0x000084D8 }, /* GL_TEXTURE24 */
-   { 34088, 0x000084D8 }, /* GL_TEXTURE24_ARB */
-   { 34105, 0x000084D9 }, /* GL_TEXTURE25 */
-   { 34118, 0x000084D9 }, /* GL_TEXTURE25_ARB */
-   { 34135, 0x000084DA }, /* GL_TEXTURE26 */
-   { 34148, 0x000084DA }, /* GL_TEXTURE26_ARB */
-   { 34165, 0x000084DB }, /* GL_TEXTURE27 */
-   { 34178, 0x000084DB }, /* GL_TEXTURE27_ARB */
-   { 34195, 0x000084DC }, /* GL_TEXTURE28 */
-   { 34208, 0x000084DC }, /* GL_TEXTURE28_ARB */
-   { 34225, 0x000084DD }, /* GL_TEXTURE29 */
-   { 34238, 0x000084DD }, /* GL_TEXTURE29_ARB */
-   { 34255, 0x000084C2 }, /* GL_TEXTURE2_ARB */
-   { 34271, 0x000084C3 }, /* GL_TEXTURE3 */
-   { 34283, 0x000084DE }, /* GL_TEXTURE30 */
-   { 34296, 0x000084DE }, /* GL_TEXTURE30_ARB */
-   { 34313, 0x000084DF }, /* GL_TEXTURE31 */
-   { 34326, 0x000084DF }, /* GL_TEXTURE31_ARB */
-   { 34343, 0x000084C3 }, /* GL_TEXTURE3_ARB */
-   { 34359, 0x000084C4 }, /* GL_TEXTURE4 */
-   { 34371, 0x000084C4 }, /* GL_TEXTURE4_ARB */
-   { 34387, 0x000084C5 }, /* GL_TEXTURE5 */
-   { 34399, 0x000084C5 }, /* GL_TEXTURE5_ARB */
-   { 34415, 0x000084C6 }, /* GL_TEXTURE6 */
-   { 34427, 0x000084C6 }, /* GL_TEXTURE6_ARB */
-   { 34443, 0x000084C7 }, /* GL_TEXTURE7 */
-   { 34455, 0x000084C7 }, /* GL_TEXTURE7_ARB */
-   { 34471, 0x000084C8 }, /* GL_TEXTURE8 */
-   { 34483, 0x000084C8 }, /* GL_TEXTURE8_ARB */
-   { 34499, 0x000084C9 }, /* GL_TEXTURE9 */
-   { 34511, 0x000084C9 }, /* GL_TEXTURE9_ARB */
-   { 34527, 0x00000DE0 }, /* GL_TEXTURE_1D */
-   { 34541, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */
-   { 34565, 0x00000DE1 }, /* GL_TEXTURE_2D */
-   { 34579, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */
-   { 34603, 0x0000806F }, /* GL_TEXTURE_3D */
-   { 34617, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
-   { 34639, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */
-   { 34665, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
-   { 34687, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
-   { 34709, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
-   { 34741, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
-   { 34763, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
-   { 34795, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
-   { 34817, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
-   { 34845, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */
-   { 34877, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
-   { 34910, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */
-   { 34942, 0x00040000 }, /* GL_TEXTURE_BIT */
-   { 34957, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
-   { 34978, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */
-   { 35003, 0x00001005 }, /* GL_TEXTURE_BORDER */
-   { 35021, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
-   { 35045, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
-   { 35076, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
-   { 35106, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
-   { 35136, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
-   { 35171, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
-   { 35202, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-   { 35240, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
-   { 35267, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
-   { 35299, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
-   { 35333, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
-   { 35357, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */
-   { 35385, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
-   { 35409, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */
-   { 35437, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
-   { 35470, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
-   { 35494, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
-   { 35516, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
-   { 35538, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */
-   { 35564, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */
-   { 35598, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
-   { 35631, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */
-   { 35668, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
-   { 35696, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */
-   { 35728, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
-   { 35751, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
-   { 35789, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */
-   { 35831, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
-   { 35862, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
-   { 35890, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
-   { 35920, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
-   { 35948, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
-   { 35968, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */
-   { 35992, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
-   { 36023, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */
-   { 36058, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
-   { 36089, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */
-   { 36124, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
-   { 36155, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */
-   { 36190, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
-   { 36221, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */
-   { 36256, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
-   { 36287, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */
-   { 36322, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
-   { 36353, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */
-   { 36388, 0x000088F4 }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
-   { 36417, 0x00008071 }, /* GL_TEXTURE_DEPTH */
-   { 36434, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
-   { 36456, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */
-   { 36482, 0x00002300 }, /* GL_TEXTURE_ENV */
-   { 36497, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
-   { 36518, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
-   { 36538, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
-   { 36564, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
-   { 36584, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
-   { 36601, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
-   { 36618, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
-   { 36635, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
-   { 36652, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
-   { 36677, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
-   { 36699, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */
-   { 36725, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
-   { 36743, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
-   { 36769, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
-   { 36795, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */
-   { 36825, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */
-   { 36852, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
-   { 36877, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
-   { 36897, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */
-   { 36921, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
-   { 36948, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
-   { 36975, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
-   { 37002, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
-   { 37028, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */
-   { 37058, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
-   { 37080, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
-   { 37098, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
-   { 37128, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
-   { 37156, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
-   { 37184, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
-   { 37212, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
-   { 37233, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
-   { 37252, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
-   { 37274, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
-   { 37293, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
-   { 37313, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
-   { 37343, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */
-   { 37374, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */
-   { 37399, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */
-   { 37423, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
-   { 37443, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */
-   { 37467, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
-   { 37487, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
-   { 37510, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */
-   { 37534, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE_EXT */
-   { 37562, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */
-   { 37592, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
-   { 37617, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
-   { 37651, 0x00001000 }, /* GL_TEXTURE_WIDTH */
-   { 37668, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
-   { 37686, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
-   { 37704, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
-   { 37722, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */
-   { 37741, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */
-   { 37761, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
-   { 37780, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
-   { 37809, 0x00001000 }, /* GL_TRANSFORM_BIT */
-   { 37826, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
-   { 37852, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */
-   { 37882, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
-   { 37914, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
-   { 37944, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */
-   { 37978, 0x0000862C }, /* GL_TRANSPOSE_NV */
-   { 37994, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
-   { 38025, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */
-   { 38060, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
-   { 38088, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */
-   { 38120, 0x00000004 }, /* GL_TRIANGLES */
-   { 38133, 0x00000006 }, /* GL_TRIANGLE_FAN */
-   { 38149, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
-   { 38170, 0x00000005 }, /* GL_TRIANGLE_STRIP */
-   { 38188, 0x00000001 }, /* GL_TRUE */
-   { 38196, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
-   { 38216, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
-   { 38239, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
-   { 38259, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
-   { 38280, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
-   { 38302, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
-   { 38324, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
-   { 38344, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
-   { 38365, 0x00009118 }, /* GL_UNSIGNALED */
-   { 38379, 0x00001401 }, /* GL_UNSIGNED_BYTE */
-   { 38396, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
-   { 38423, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
-   { 38446, 0x00001405 }, /* GL_UNSIGNED_INT */
-   { 38462, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
-   { 38489, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */
-   { 38510, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_EXT */
-   { 38535, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */
-   { 38559, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
-   { 38590, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
-   { 38614, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
-   { 38642, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */
-   { 38665, 0x00001403 }, /* GL_UNSIGNED_SHORT */
-   { 38683, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
-   { 38713, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
-   { 38739, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
-   { 38769, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
-   { 38795, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
-   { 38819, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
-   { 38847, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
-   { 38875, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */
-   { 38902, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
-   { 38934, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */
-   { 38965, 0x00008CA2 }, /* GL_UPPER_LEFT */
-   { 38979, 0x00002A20 }, /* GL_V2F */
-   { 38986, 0x00002A21 }, /* GL_V3F */
-   { 38993, 0x00008B83 }, /* GL_VALIDATE_STATUS */
-   { 39012, 0x00001F00 }, /* GL_VENDOR */
-   { 39022, 0x00001F02 }, /* GL_VERSION */
-   { 39033, 0x00008074 }, /* GL_VERTEX_ARRAY */
-   { 39049, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */
-   { 39073, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */
-   { 39103, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
-   { 39134, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */
-   { 39169, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
-   { 39193, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
-   { 39214, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
-   { 39237, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
-   { 39258, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
-   { 39285, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
-   { 39313, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
-   { 39341, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
-   { 39369, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
-   { 39397, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
-   { 39425, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
-   { 39453, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
-   { 39480, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
-   { 39507, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
-   { 39534, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
-   { 39561, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
-   { 39588, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
-   { 39615, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
-   { 39642, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
-   { 39669, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
-   { 39696, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
-   { 39734, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */
-   { 39776, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
-   { 39807, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
-   { 39842, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
-   { 39876, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
-   { 39914, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
-   { 39945, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
-   { 39980, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
-   { 40008, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
-   { 40040, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
-   { 40070, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
-   { 40104, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
-   { 40132, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
-   { 40164, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
-   { 40184, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
-   { 40206, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
-   { 40235, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */
-   { 40256, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */
-   { 40285, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
-   { 40318, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
-   { 40350, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */
-   { 40377, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
-   { 40408, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
-   { 40438, 0x00008B31 }, /* GL_VERTEX_SHADER */
-   { 40455, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */
-   { 40476, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
-   { 40503, 0x00000BA2 }, /* GL_VIEWPORT */
-   { 40515, 0x00000800 }, /* GL_VIEWPORT_BIT */
-   { 40531, 0x0000911D }, /* GL_WAIT_FAILED */
-   { 40546, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
-   { 40566, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
-   { 40597, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */
-   { 40632, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
-   { 40660, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
-   { 40685, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
-   { 40712, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
-   { 40737, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
-   { 40761, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
-   { 40780, 0x000088B9 }, /* GL_WRITE_ONLY */
-   { 40794, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */
-   { 40812, 0x00001506 }, /* GL_XOR */
-   { 40819, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
-   { 40838, 0x00008757 }, /* GL_YCBCR_MESA */
-   { 40852, 0x00000000 }, /* GL_ZERO */
-   { 40860, 0x00000D16 }, /* GL_ZOOM_X */
-   { 40870, 0x00000D17 }, /* GL_ZOOM_Y */
+   { 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[1346] =
+static const unsigned reduced_enums[1350] =
 {
        479, /* GL_FALSE */
        701, /* GL_LINES */
        703, /* GL_LINE_LOOP */
        710, /* GL_LINE_STRIP */
-      1765, /* GL_TRIANGLES */
-      1768, /* GL_TRIANGLE_STRIP */
-      1766, /* GL_TRIANGLE_FAN */
+      1769, /* GL_TRIANGLES */
+      1772, /* GL_TRIANGLE_STRIP */
+      1770, /* GL_TRIANGLE_FAN */
       1285, /* GL_QUADS */
       1289, /* GL_QUAD_STRIP */
       1171, /* GL_POLYGON */
@@ -3820,7 +3828,7 @@
        509, /* GL_FOG_BIT */
          8, /* GL_ACCUM */
        720, /* GL_LOAD */
-      1344, /* GL_RETURN */
+      1348, /* GL_RETURN */
       1004, /* GL_MULT */
         23, /* GL_ADD */
       1020, /* GL_NEVER */
@@ -3831,15 +3839,15 @@
       1035, /* GL_NOTEQUAL */
        598, /* GL_GEQUAL */
         47, /* GL_ALWAYS */
-      1485, /* GL_SRC_COLOR */
+      1489, /* GL_SRC_COLOR */
       1065, /* GL_ONE_MINUS_SRC_COLOR */
-      1483, /* GL_SRC_ALPHA */
+      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 */
-      1484, /* GL_SRC_ALPHA_SATURATE */
+      1488, /* GL_SRC_ALPHA_SATURATE */
        586, /* GL_FRONT_LEFT */
        587, /* GL_FRONT_RIGHT */
         69, /* GL_BACK_LEFT */
@@ -3847,7 +3855,7 @@
        583, /* GL_FRONT */
         68, /* GL_BACK */
        676, /* GL_LEFT */
-      1386, /* GL_RIGHT */
+      1390, /* GL_RIGHT */
        584, /* GL_FRONT_AND_BACK */
         63, /* GL_AUX0 */
         64, /* GL_AUX1 */
@@ -3856,8 +3864,8 @@
        665, /* GL_INVALID_ENUM */
        669, /* GL_INVALID_VALUE */
        668, /* GL_INVALID_OPERATION */
-      1490, /* GL_STACK_OVERFLOW */
-      1491, /* GL_STACK_UNDERFLOW */
+      1494, /* GL_STACK_OVERFLOW */
+      1495, /* GL_STACK_UNDERFLOW */
       1090, /* GL_OUT_OF_MEMORY */
        666, /* GL_INVALID_FRAMEBUFFER_OPERATION */
          0, /* GL_2D */
@@ -3916,7 +3924,7 @@
        692, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
        693, /* GL_LIGHT_MODEL_TWO_SIDE */
        689, /* GL_LIGHT_MODEL_AMBIENT */
-      1432, /* GL_SHADE_MODEL */
+      1436, /* GL_SHADE_MODEL */
        193, /* GL_COLOR_MATERIAL_FACE */
        194, /* GL_COLOR_MATERIAL_PARAMETER */
        192, /* GL_COLOR_MATERIAL */
@@ -3933,24 +3941,24 @@
        358, /* GL_DEPTH_CLEAR_VALUE */
        369, /* GL_DEPTH_FUNC */
         12, /* GL_ACCUM_CLEAR_VALUE */
-      1530, /* GL_STENCIL_TEST */
-      1514, /* GL_STENCIL_CLEAR_VALUE */
-      1516, /* GL_STENCIL_FUNC */
-      1532, /* GL_STENCIL_VALUE_MASK */
-      1515, /* GL_STENCIL_FAIL */
-      1527, /* GL_STENCIL_PASS_DEPTH_FAIL */
-      1528, /* GL_STENCIL_PASS_DEPTH_PASS */
-      1529, /* GL_STENCIL_REF */
-      1533, /* GL_STENCIL_WRITEMASK */
+      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 */
-      1860, /* GL_VIEWPORT */
+      1864, /* GL_VIEWPORT */
        999, /* GL_MODELVIEW_STACK_DEPTH */
       1263, /* GL_PROJECTION_STACK_DEPTH */
-      1740, /* GL_TEXTURE_STACK_DEPTH */
+      1744, /* GL_TEXTURE_STACK_DEPTH */
        997, /* GL_MODELVIEW_MATRIX */
       1262, /* GL_PROJECTION_MATRIX */
-      1723, /* GL_TEXTURE_MATRIX */
+      1727, /* GL_TEXTURE_MATRIX */
         61, /* GL_ATTRIB_STACK_DEPTH */
        136, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
         43, /* GL_ALPHA_TEST */
@@ -3965,27 +3973,27 @@
        191, /* GL_COLOR_LOGIC_OP */
         67, /* GL_AUX_BUFFERS */
        394, /* GL_DRAW_BUFFER */
-      1299, /* GL_READ_BUFFER */
-      1413, /* GL_SCISSOR_BOX */
-      1414, /* GL_SCISSOR_TEST */
+      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 */
        640, /* GL_INDEX_MODE */
-      1379, /* GL_RGBA_MODE */
+      1383, /* GL_RGBA_MODE */
        393, /* GL_DOUBLEBUFFER */
-      1534, /* GL_STEREO */
-      1337, /* GL_RENDER_MODE */
+      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 */
-      1704, /* GL_TEXTURE_GEN_S */
-      1705, /* GL_TEXTURE_GEN_T */
-      1703, /* GL_TEXTURE_GEN_R */
-      1702, /* GL_TEXTURE_GEN_Q */
+      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 */
@@ -4006,12 +4014,12 @@
       1117, /* GL_PIXEL_MAP_G_TO_G_SIZE */
       1115, /* GL_PIXEL_MAP_B_TO_B_SIZE */
       1113, /* GL_PIXEL_MAP_A_TO_A_SIZE */
-      1777, /* GL_UNPACK_SWAP_BYTES */
-      1772, /* GL_UNPACK_LSB_FIRST */
-      1773, /* GL_UNPACK_ROW_LENGTH */
-      1776, /* GL_UNPACK_SKIP_ROWS */
-      1775, /* GL_UNPACK_SKIP_PIXELS */
-      1770, /* GL_UNPACK_ALIGNMENT */
+      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 */
@@ -4022,10 +4030,10 @@
        805, /* GL_MAP_STENCIL */
        642, /* GL_INDEX_SHIFT */
        641, /* GL_INDEX_OFFSET */
-      1313, /* GL_RED_SCALE */
-      1311, /* GL_RED_BIAS */
-      1878, /* GL_ZOOM_X */
-      1879, /* GL_ZOOM_Y */
+      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 */
@@ -4046,14 +4054,14 @@
        933, /* GL_MAX_TEXTURE_STACK_DEPTH */
        947, /* GL_MAX_VIEWPORT_DIMS */
        859, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
-      1544, /* GL_SUBPIXEL_BITS */
+      1548, /* GL_SUBPIXEL_BITS */
        637, /* GL_INDEX_BITS */
-      1312, /* GL_RED_BITS */
+      1316, /* GL_RED_BITS */
        602, /* GL_GREEN_BITS */
         92, /* GL_BLUE_BITS */
         41, /* GL_ALPHA_BITS */
        352, /* GL_DEPTH_BITS */
-      1512, /* GL_STENCIL_BITS */
+      1516, /* GL_STENCIL_BITS */
         14, /* GL_ACCUM_RED_BITS */
         13, /* GL_ACCUM_GREEN_BITS */
         10, /* GL_ACCUM_BLUE_BITS */
@@ -4082,39 +4090,39 @@
        748, /* GL_MAP1_GRID_SEGMENTS */
        774, /* GL_MAP2_GRID_DOMAIN */
        775, /* GL_MAP2_GRID_SEGMENTS */
-      1627, /* GL_TEXTURE_1D */
-      1629, /* GL_TEXTURE_2D */
+      1631, /* GL_TEXTURE_1D */
+      1633, /* GL_TEXTURE_2D */
        482, /* GL_FEEDBACK_BUFFER_POINTER */
        483, /* GL_FEEDBACK_BUFFER_SIZE */
        484, /* GL_FEEDBACK_BUFFER_TYPE */
-      1423, /* GL_SELECTION_BUFFER_POINTER */
-      1424, /* GL_SELECTION_BUFFER_SIZE */
-      1746, /* GL_TEXTURE_WIDTH */
-      1709, /* GL_TEXTURE_HEIGHT */
-      1664, /* GL_TEXTURE_COMPONENTS */
-      1648, /* GL_TEXTURE_BORDER_COLOR */
-      1647, /* GL_TEXTURE_BORDER */
+      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 */
        382, /* GL_DIFFUSE */
-      1472, /* GL_SPECULAR */
+      1476, /* GL_SPECULAR */
       1185, /* GL_POSITION */
-      1475, /* GL_SPOT_DIRECTION */
-      1476, /* GL_SPOT_EXPONENT */
-      1474, /* GL_SPOT_CUTOFF */
+      1479, /* GL_SPOT_DIRECTION */
+      1480, /* GL_SPOT_EXPONENT */
+      1478, /* GL_SPOT_CUTOFF */
        275, /* GL_CONSTANT_ATTENUATION */
        696, /* GL_LINEAR_ATTENUATION */
       1284, /* GL_QUADRATIC_ATTENUATION */
        244, /* GL_COMPILE */
        245, /* GL_COMPILE_AND_EXECUTE */
        120, /* GL_BYTE */
-      1779, /* GL_UNSIGNED_BYTE */
-      1437, /* GL_SHORT */
-      1791, /* GL_UNSIGNED_SHORT */
+      1783, /* GL_UNSIGNED_BYTE */
+      1441, /* GL_SHORT */
+      1795, /* GL_UNSIGNED_SHORT */
        645, /* GL_INT */
-      1782, /* GL_UNSIGNED_INT */
+      1786, /* GL_UNSIGNED_INT */
        489, /* GL_FLOAT */
          1, /* GL_2_BYTES */
          5, /* GL_3_BYTES */
@@ -4126,7 +4134,7 @@
        299, /* GL_COPY */
         51, /* GL_AND_INVERTED */
       1023, /* GL_NOOP */
-      1874, /* GL_XOR */
+      1878, /* GL_XOR */
       1086, /* GL_OR */
       1024, /* GL_NOR */
        470, /* GL_EQUIV */
@@ -4135,58 +4143,58 @@
        300, /* GL_COPY_INVERTED */
       1088, /* GL_OR_INVERTED */
       1014, /* GL_NAND */
-      1428, /* GL_SET */
+      1432, /* GL_SET */
        467, /* GL_EMISSION */
-      1436, /* GL_SHININESS */
+      1440, /* GL_SHININESS */
         49, /* GL_AMBIENT_AND_DIFFUSE */
        190, /* GL_COLOR_INDEXES */
        964, /* GL_MODELVIEW */
       1261, /* GL_PROJECTION */
-      1562, /* GL_TEXTURE */
+      1566, /* GL_TEXTURE */
        147, /* GL_COLOR */
        346, /* GL_DEPTH */
-      1498, /* GL_STENCIL */
+      1502, /* GL_STENCIL */
        189, /* GL_COLOR_INDEX */
-      1517, /* GL_STENCIL_INDEX */
+      1521, /* GL_STENCIL_INDEX */
        359, /* GL_DEPTH_COMPONENT */
-      1308, /* GL_RED */
+      1312, /* GL_RED */
        600, /* GL_GREEN */
         90, /* GL_BLUE */
         31, /* GL_ALPHA */
-      1345, /* GL_RGB */
-      1364, /* GL_RGBA */
+      1349, /* GL_RGB */
+      1368, /* GL_RGBA */
        724, /* GL_LUMINANCE */
        745, /* GL_LUMINANCE_ALPHA */
         73, /* GL_BITMAP */
       1141, /* GL_POINT */
        694, /* GL_LINE */
        485, /* GL_FILL */
-      1317, /* GL_RENDER */
+      1321, /* GL_RENDER */
        481, /* GL_FEEDBACK */
-      1422, /* GL_SELECT */
+      1426, /* GL_SELECT */
        488, /* GL_FLAT */
-      1447, /* GL_SMOOTH */
+      1451, /* GL_SMOOTH */
        673, /* GL_KEEP */
-      1339, /* GL_REPLACE */
+      1343, /* GL_REPLACE */
        627, /* GL_INCR */
        342, /* GL_DECR */
-      1806, /* GL_VENDOR */
-      1336, /* GL_RENDERER */
-      1807, /* GL_VERSION */
+      1810, /* GL_VENDOR */
+      1340, /* GL_RENDERER */
+      1811, /* GL_VERSION */
        474, /* GL_EXTENSIONS */
-      1387, /* GL_S */
-      1553, /* GL_T */
-      1296, /* GL_R */
+      1391, /* GL_S */
+      1557, /* GL_T */
+      1300, /* GL_R */
       1283, /* GL_Q */
       1000, /* GL_MODULATE */
        341, /* GL_DECAL */
-      1699, /* GL_TEXTURE_ENV_MODE */
-      1698, /* GL_TEXTURE_ENV_COLOR */
-      1697, /* GL_TEXTURE_ENV */
+      1703, /* GL_TEXTURE_ENV_MODE */
+      1702, /* GL_TEXTURE_ENV_COLOR */
+      1701, /* GL_TEXTURE_ENV */
        475, /* GL_EYE_LINEAR */
       1047, /* GL_OBJECT_LINEAR */
-      1473, /* GL_SPHERE_MAP */
-      1701, /* GL_TEXTURE_GEN_MODE */
+      1477, /* GL_SPHERE_MAP */
+      1705, /* GL_TEXTURE_GEN_MODE */
       1049, /* GL_OBJECT_PLANE */
        476, /* GL_EYE_PLANE */
       1015, /* GL_NEAREST */
@@ -4195,30 +4203,30 @@
        700, /* GL_LINEAR_MIPMAP_NEAREST */
       1018, /* GL_NEAREST_MIPMAP_LINEAR */
        699, /* GL_LINEAR_MIPMAP_LINEAR */
-      1722, /* GL_TEXTURE_MAG_FILTER */
-      1730, /* GL_TEXTURE_MIN_FILTER */
-      1748, /* GL_TEXTURE_WRAP_S */
-      1749, /* GL_TEXTURE_WRAP_T */
+      1726, /* GL_TEXTURE_MAG_FILTER */
+      1734, /* GL_TEXTURE_MIN_FILTER */
+      1752, /* GL_TEXTURE_WRAP_S */
+      1753, /* GL_TEXTURE_WRAP_T */
        126, /* GL_CLAMP */
-      1338, /* GL_REPEAT */
+      1342, /* GL_REPEAT */
       1179, /* GL_POLYGON_OFFSET_UNITS */
       1178, /* GL_POLYGON_OFFSET_POINT */
       1177, /* GL_POLYGON_OFFSET_LINE */
-      1297, /* GL_R3_G3_B2 */
-      1803, /* GL_V2F */
-      1804, /* GL_V3F */
+      1301, /* GL_R3_G3_B2 */
+      1807, /* GL_V2F */
+      1808, /* GL_V3F */
        123, /* GL_C4UB_V2F */
        124, /* GL_C4UB_V3F */
        121, /* GL_C3F_V3F */
       1012, /* GL_N3F_V3F */
        122, /* GL_C4F_N3F_V3F */
-      1558, /* GL_T2F_V3F */
-      1560, /* GL_T4F_V4F */
-      1556, /* GL_T2F_C4UB_V3F */
-      1554, /* GL_T2F_C3F_V3F */
-      1557, /* GL_T2F_N3F_V3F */
-      1555, /* GL_T2F_C4F_N3F_V3F */
-      1559, /* 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 */
@@ -4247,11 +4255,11 @@
        590, /* GL_FUNC_REVERSE_SUBTRACT */
        280, /* GL_CONVOLUTION_1D */
        281, /* GL_CONVOLUTION_2D */
-      1425, /* GL_SEPARABLE_2D */
+      1429, /* GL_SEPARABLE_2D */
        284, /* GL_CONVOLUTION_BORDER_MODE */
        288, /* GL_CONVOLUTION_FILTER_SCALE */
        286, /* GL_CONVOLUTION_FILTER_BIAS */
-      1309, /* GL_REDUCE */
+      1313, /* GL_REDUCE */
        290, /* GL_CONVOLUTION_FORMAT */
        294, /* GL_CONVOLUTION_WIDTH */
        292, /* GL_CONVOLUTION_HEIGHT */
@@ -4278,16 +4286,16 @@
        949, /* GL_MINMAX */
        951, /* GL_MINMAX_FORMAT */
        953, /* GL_MINMAX_SINK */
-      1561, /* GL_TABLE_TOO_LARGE_EXT */
-      1781, /* GL_UNSIGNED_BYTE_3_3_2 */
-      1793, /* GL_UNSIGNED_SHORT_4_4_4_4 */
-      1795, /* GL_UNSIGNED_SHORT_5_5_5_1 */
-      1788, /* GL_UNSIGNED_INT_8_8_8_8 */
-      1783, /* GL_UNSIGNED_INT_10_10_10_2 */
+      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 */
-      1342, /* GL_RESCALE_NORMAL */
+      1346, /* GL_RESCALE_NORMAL */
         36, /* GL_ALPHA4 */
         38, /* GL_ALPHA8 */
         32, /* GL_ALPHA12 */
@@ -4307,53 +4315,53 @@
        653, /* GL_INTENSITY8 */
        647, /* GL_INTENSITY12 */
        649, /* GL_INTENSITY16 */
-      1354, /* GL_RGB2_EXT */
-      1355, /* GL_RGB4 */
-      1358, /* GL_RGB5 */
-      1362, /* GL_RGB8 */
-      1346, /* GL_RGB10 */
-      1350, /* GL_RGB12 */
-      1352, /* GL_RGB16 */
-      1369, /* GL_RGBA2 */
-      1371, /* GL_RGBA4 */
-      1359, /* GL_RGB5_A1 */
-      1375, /* GL_RGBA8 */
-      1347, /* GL_RGB10_A2 */
-      1365, /* GL_RGBA12 */
-      1367, /* GL_RGBA16 */
-      1737, /* GL_TEXTURE_RED_SIZE */
-      1707, /* GL_TEXTURE_GREEN_SIZE */
-      1645, /* GL_TEXTURE_BLUE_SIZE */
-      1632, /* GL_TEXTURE_ALPHA_SIZE */
-      1720, /* GL_TEXTURE_LUMINANCE_SIZE */
-      1711, /* GL_TEXTURE_INTENSITY_SIZE */
-      1340, /* GL_REPLACE_EXT */
+      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 */
-      1744, /* GL_TEXTURE_TOO_LARGE_EXT */
-      1732, /* GL_TEXTURE_PRIORITY */
-      1739, /* GL_TEXTURE_RESIDENT */
-      1635, /* GL_TEXTURE_BINDING_1D */
-      1637, /* GL_TEXTURE_BINDING_2D */
-      1639, /* GL_TEXTURE_BINDING_3D */
+      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 */
-      1774, /* GL_UNPACK_SKIP_IMAGES */
-      1771, /* GL_UNPACK_IMAGE_HEIGHT */
-      1631, /* GL_TEXTURE_3D */
+      1778, /* GL_UNPACK_SKIP_IMAGES */
+      1775, /* GL_UNPACK_IMAGE_HEIGHT */
+      1635, /* GL_TEXTURE_3D */
       1277, /* GL_PROXY_TEXTURE_3D */
-      1694, /* GL_TEXTURE_DEPTH */
-      1747, /* GL_TEXTURE_WRAP_R */
+      1698, /* GL_TEXTURE_DEPTH */
+      1751, /* GL_TEXTURE_WRAP_R */
        856, /* GL_MAX_3D_TEXTURE_SIZE */
-      1808, /* GL_VERTEX_ARRAY */
+      1812, /* GL_VERTEX_ARRAY */
       1026, /* GL_NORMAL_ARRAY */
        148, /* GL_COLOR_ARRAY */
        631, /* GL_INDEX_ARRAY */
-      1672, /* GL_TEXTURE_COORD_ARRAY */
+      1676, /* GL_TEXTURE_COORD_ARRAY */
        459, /* GL_EDGE_FLAG_ARRAY */
-      1814, /* GL_VERTEX_ARRAY_SIZE */
-      1816, /* GL_VERTEX_ARRAY_TYPE */
-      1815, /* GL_VERTEX_ARRAY_STRIDE */
+      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 */
@@ -4361,24 +4369,24 @@
        153, /* GL_COLOR_ARRAY_STRIDE */
        636, /* GL_INDEX_ARRAY_TYPE */
        635, /* GL_INDEX_ARRAY_STRIDE */
-      1676, /* GL_TEXTURE_COORD_ARRAY_SIZE */
-      1678, /* GL_TEXTURE_COORD_ARRAY_TYPE */
-      1677, /* GL_TEXTURE_COORD_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 */
-      1813, /* GL_VERTEX_ARRAY_POINTER */
+      1817, /* GL_VERTEX_ARRAY_POINTER */
       1029, /* GL_NORMAL_ARRAY_POINTER */
        151, /* GL_COLOR_ARRAY_POINTER */
        634, /* GL_INDEX_ARRAY_POINTER */
-      1675, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+      1679, /* GL_TEXTURE_COORD_ARRAY_POINTER */
        462, /* GL_EDGE_FLAG_ARRAY_POINTER */
       1005, /* GL_MULTISAMPLE */
-      1399, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
-      1401, /* GL_SAMPLE_ALPHA_TO_ONE */
-      1406, /* GL_SAMPLE_COVERAGE */
-      1403, /* GL_SAMPLE_BUFFERS */
-      1394, /* GL_SAMPLES */
-      1410, /* GL_SAMPLE_COVERAGE_VALUE */
-      1408, /* GL_SAMPLE_COVERAGE_INVERT */
+      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 */
        865, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
@@ -4390,9 +4398,9 @@
       1195, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
       1190, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
       1186, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
-      1655, /* GL_TEXTURE_COLOR_TABLE_SGI */
+      1659, /* GL_TEXTURE_COLOR_TABLE_SGI */
       1278, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
-      1657, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+      1661, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
         80, /* GL_BLEND_DST_RGB */
         89, /* GL_BLEND_SRC_RGB */
         79, /* GL_BLEND_DST_ALPHA */
@@ -4417,7 +4425,7 @@
         72, /* GL_BGRA */
        879, /* GL_MAX_ELEMENTS_VERTICES */
        878, /* GL_MAX_ELEMENTS_INDICES */
-      1710, /* GL_TEXTURE_INDEX_SIZE_EXT */
+      1714, /* GL_TEXTURE_INDEX_SIZE_EXT */
        145, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
       1158, /* GL_POINT_SIZE_MIN */
       1154, /* GL_POINT_SIZE_MAX */
@@ -4425,52 +4433,52 @@
       1144, /* GL_POINT_DISTANCE_ATTENUATION */
        127, /* GL_CLAMP_TO_BORDER */
        130, /* GL_CLAMP_TO_EDGE */
-      1731, /* GL_TEXTURE_MIN_LOD */
-      1729, /* GL_TEXTURE_MAX_LOD */
-      1634, /* GL_TEXTURE_BASE_LEVEL */
-      1728, /* GL_TEXTURE_MAX_LEVEL */
+      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 */
-      1341, /* GL_REPLICATE_BORDER_HP */
+      1345, /* GL_REPLICATE_BORDER_HP */
        282, /* GL_CONVOLUTION_BORDER_COLOR */
       1055, /* GL_OCCLUSION_TEST_HP */
       1056, /* GL_OCCLUSION_TEST_RESULT_HP */
        697, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
-      1649, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
-      1651, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
-      1653, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
-      1654, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-      1652, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
-      1650, /* GL_TEXTURE_CLIPMAP_DEPTH_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 */
-      1718, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
-      1719, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
-      1717, /* GL_TEXTURE_LOD_BIAS_R_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 */
-      1663, /* GL_TEXTURE_COMPARE_SGIX */
-      1662, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
-      1714, /* GL_TEXTURE_LEQUAL_R_SGIX */
-      1706, /* GL_TEXTURE_GEQUAL_R_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 */
-      1871, /* GL_WRAP_BORDER_SUN */
-      1656, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+      1875, /* GL_WRAP_BORDER_SUN */
+      1660, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
        690, /* GL_LIGHT_MODEL_COLOR_CONTROL */
-      1440, /* GL_SINGLE_COLOR */
-      1426, /* GL_SEPARATE_SPECULAR_COLOR */
-      1435, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+      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 */
@@ -4483,23 +4491,23 @@
        580, /* GL_FRAMEBUFFER_UNDEFINED */
        373, /* GL_DEPTH_STENCIL_ATTACHMENT */
        630, /* GL_INDEX */
-      1780, /* GL_UNSIGNED_BYTE_2_3_3_REV */
-      1796, /* GL_UNSIGNED_SHORT_5_6_5 */
-      1797, /* GL_UNSIGNED_SHORT_5_6_5_REV */
-      1794, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
-      1792, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
-      1789, /* GL_UNSIGNED_INT_8_8_8_8_REV */
-      1787, /* GL_UNSIGNED_INT_2_10_10_10_REV */
-      1726, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
-      1727, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
-      1725, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+      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 */
-      1382, /* GL_RGB_S3TC */
-      1357, /* GL_RGB4_S3TC */
-      1380, /* GL_RGBA_S3TC */
-      1374, /* GL_RGBA4_S3TC */
-      1378, /* GL_RGBA_DXT5_S3TC */
-      1372, /* GL_RGBA4_DXT5_S3TC */
+      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 */
@@ -4517,54 +4525,54 @@
        513, /* GL_FOG_COORDINATE_ARRAY */
        199, /* GL_COLOR_SUM */
        332, /* GL_CURRENT_SECONDARY_COLOR */
-      1419, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
-      1421, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
-      1420, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
-      1418, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
-      1415, /* 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 */
-      1563, /* GL_TEXTURE0 */
-      1565, /* GL_TEXTURE1 */
-      1587, /* GL_TEXTURE2 */
-      1609, /* GL_TEXTURE3 */
-      1615, /* GL_TEXTURE4 */
-      1617, /* GL_TEXTURE5 */
-      1619, /* GL_TEXTURE6 */
-      1621, /* GL_TEXTURE7 */
-      1623, /* GL_TEXTURE8 */
-      1625, /* GL_TEXTURE9 */
-      1566, /* GL_TEXTURE10 */
-      1568, /* GL_TEXTURE11 */
-      1570, /* GL_TEXTURE12 */
-      1572, /* GL_TEXTURE13 */
-      1574, /* GL_TEXTURE14 */
-      1576, /* GL_TEXTURE15 */
-      1578, /* GL_TEXTURE16 */
-      1580, /* GL_TEXTURE17 */
-      1582, /* GL_TEXTURE18 */
-      1584, /* GL_TEXTURE19 */
-      1588, /* GL_TEXTURE20 */
-      1590, /* GL_TEXTURE21 */
-      1592, /* GL_TEXTURE22 */
-      1594, /* GL_TEXTURE23 */
-      1596, /* GL_TEXTURE24 */
-      1598, /* GL_TEXTURE25 */
-      1600, /* GL_TEXTURE26 */
-      1602, /* GL_TEXTURE27 */
-      1604, /* GL_TEXTURE28 */
-      1606, /* GL_TEXTURE29 */
-      1610, /* GL_TEXTURE30 */
-      1612, /* 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 */
        934, /* GL_MAX_TEXTURE_UNITS */
-      1758, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
-      1761, /* GL_TRANSPOSE_PROJECTION_MATRIX */
-      1763, /* GL_TRANSPOSE_TEXTURE_MATRIX */
-      1755, /* GL_TRANSPOSE_COLOR_MATRIX */
-      1545, /* GL_SUBTRACT */
+      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 */
@@ -4572,18 +4580,18 @@
        249, /* GL_COMPRESSED_INTENSITY */
        255, /* GL_COMPRESSED_RGB */
        256, /* GL_COMPRESSED_RGBA */
-      1670, /* GL_TEXTURE_COMPRESSION_HINT */
-      1735, /* GL_TEXTURE_RECTANGLE_ARB */
-      1642, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
+      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 */
-      1784, /* GL_UNSIGNED_INT_24_8 */
+      1788, /* GL_UNSIGNED_INT_24_8 */
        930, /* GL_MAX_TEXTURE_LOD_BIAS */
-      1724, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+      1728, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
        931, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
-      1700, /* GL_TEXTURE_FILTER_CONTROL */
-      1715, /* GL_TEXTURE_LOD_BIAS */
+      1704, /* GL_TEXTURE_FILTER_CONTROL */
+      1719, /* GL_TEXTURE_LOD_BIAS */
        232, /* GL_COMBINE4 */
        924, /* GL_MAX_SHININESS_NV */
        925, /* GL_MAX_SPOT_EXPONENT_NV */
@@ -4591,15 +4599,15 @@
        343, /* GL_DECR_WRAP */
        976, /* GL_MODELVIEW1_ARB */
       1032, /* GL_NORMAL_MAP */
-      1314, /* GL_REFLECTION_MAP */
-      1679, /* GL_TEXTURE_CUBE_MAP */
-      1640, /* GL_TEXTURE_BINDING_CUBE_MAP */
-      1687, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
-      1681, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
-      1689, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
-      1683, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
-      1691, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
-      1685, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+      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 */
@@ -4609,20 +4617,20 @@
        231, /* GL_COMBINE */
        238, /* GL_COMBINE_RGB */
        233, /* GL_COMBINE_ALPHA */
-      1383, /* GL_RGB_SCALE */
+      1387, /* GL_RGB_SCALE */
         24, /* GL_ADD_SIGNED */
        656, /* GL_INTERPOLATE */
        271, /* GL_CONSTANT */
       1227, /* GL_PRIMARY_COLOR */
       1224, /* GL_PREVIOUS */
-      1455, /* GL_SOURCE0_RGB */
-      1461, /* GL_SOURCE1_RGB */
-      1467, /* GL_SOURCE2_RGB */
-      1471, /* GL_SOURCE3_RGB_NV */
-      1452, /* GL_SOURCE0_ALPHA */
-      1458, /* GL_SOURCE1_ALPHA */
-      1464, /* GL_SOURCE2_ALPHA */
-      1470, /* GL_SOURCE3_ALPHA_NV */
+      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 */
@@ -4631,32 +4639,32 @@
       1072, /* GL_OPERAND1_ALPHA */
       1078, /* GL_OPERAND2_ALPHA */
       1084, /* GL_OPERAND3_ALPHA_NV */
-      1809, /* GL_VERTEX_ARRAY_BINDING */
-      1733, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
-      1734, /* GL_TEXTURE_RANGE_POINTER_APPLE */
-      1875, /* GL_YCBCR_422_APPLE */
-      1798, /* GL_UNSIGNED_SHORT_8_8_APPLE */
-      1800, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
-      1743, /* GL_TEXTURE_STORAGE_HINT_APPLE */
-      1536, /* GL_STORAGE_PRIVATE_APPLE */
-      1535, /* GL_STORAGE_CACHED_APPLE */
-      1537, /* GL_STORAGE_SHARED_APPLE */
-      1442, /* GL_SLICE_ACCUM_SUN */
+      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 */
-      1767, /* GL_TRIANGLE_MESH_SUN */
-      1848, /* GL_VERTEX_PROGRAM_ARB */
-      1859, /* GL_VERTEX_STATE_PROGRAM_NV */
-      1835, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
-      1841, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
-      1843, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
-      1845, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
+      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 */
       1240, /* GL_PROGRAM_LENGTH_ARB */
       1254, /* GL_PROGRAM_STRING_ARB */
        998, /* GL_MODELVIEW_PROJECTION_NV */
        623, /* GL_IDENTITY_NV */
        670, /* GL_INVERSE_NV */
-      1760, /* GL_TRANSPOSE_NV */
+      1764, /* GL_TRANSPOSE_NV */
        671, /* GL_INVERSE_TRANSPOSE_NV */
        903, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
        902, /* GL_MAX_PROGRAM_MATRICES_ARB */
@@ -4670,33 +4678,33 @@
        845, /* GL_MATRIX7_NV */
        318, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
        315, /* GL_CURRENT_MATRIX_ARB */
-      1851, /* GL_VERTEX_PROGRAM_POINT_SIZE */
-      1854, /* GL_VERTEX_PROGRAM_TWO_SIDE */
+      1855, /* GL_VERTEX_PROGRAM_POINT_SIZE */
+      1858, /* GL_VERTEX_PROGRAM_TWO_SIDE */
       1252, /* GL_PROGRAM_PARAMETER_NV */
-      1839, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
+      1843, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
       1256, /* GL_PROGRAM_TARGET_NV */
       1253, /* GL_PROGRAM_RESIDENT_NV */
-      1752, /* GL_TRACK_MATRIX_NV */
-      1753, /* GL_TRACK_MATRIX_TRANSFORM_NV */
-      1849, /* GL_VERTEX_PROGRAM_BINDING_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 */
-      1817, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
-      1824, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
-      1825, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
-      1826, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
-      1827, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
-      1828, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
-      1829, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
-      1830, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
-      1831, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
-      1832, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
-      1818, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
-      1819, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
-      1820, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
-      1821, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
-      1822, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
-      1823, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+      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 */
@@ -4729,27 +4737,27 @@
        788, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
        789, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
        790, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
-      1668, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
-      1665, /* GL_TEXTURE_COMPRESSED */
+      1672, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+      1669, /* GL_TEXTURE_COMPRESSED */
       1037, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
        269, /* GL_COMPRESSED_TEXTURE_FORMATS */
        946, /* GL_MAX_VERTEX_UNITS_ARB */
         22, /* GL_ACTIVE_VERTEX_UNITS_ARB */
-      1870, /* GL_WEIGHT_SUM_UNITY_ARB */
-      1847, /* GL_VERTEX_BLEND_ARB */
+      1874, /* GL_WEIGHT_SUM_UNITY_ARB */
+      1851, /* GL_VERTEX_BLEND_ARB */
        336, /* GL_CURRENT_WEIGHT_ARB */
-      1869, /* GL_WEIGHT_ARRAY_TYPE_ARB */
-      1868, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
-      1867, /* GL_WEIGHT_ARRAY_SIZE_ARB */
-      1866, /* GL_WEIGHT_ARRAY_POINTER_ARB */
-      1863, /* GL_WEIGHT_ARRAY_ARB */
+      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 */
       1006, /* GL_MULTISAMPLE_3DFX */
-      1404, /* GL_SAMPLE_BUFFERS_3DFX */
-      1395, /* GL_SAMPLES_3DFX */
+      1408, /* GL_SAMPLE_BUFFERS_3DFX */
+      1399, /* GL_SAMPLES_3DFX */
        987, /* GL_MODELVIEW2_ARB */
        990, /* GL_MODELVIEW3_ARB */
        991, /* GL_MODELVIEW4_ARB */
@@ -4787,7 +4795,7 @@
       1001, /* GL_MODULATE_ADD_ATI */
       1002, /* GL_MODULATE_SIGNED_ADD_ATI */
       1003, /* GL_MODULATE_SUBTRACT_ATI */
-      1876, /* GL_YCBCR_MESA */
+      1880, /* GL_YCBCR_MESA */
       1093, /* GL_PACK_INVERT_MESA */
        339, /* GL_DEBUG_OBJECT_MESA */
        340, /* GL_DEBUG_PRINT_MESA */
@@ -4802,10 +4810,10 @@
        450, /* GL_DU8DV8_ATI */
        114, /* GL_BUMP_ENVMAP_ATI */
        118, /* GL_BUMP_TARGET_ATI */
-      1503, /* GL_STENCIL_BACK_FUNC */
-      1501, /* GL_STENCIL_BACK_FAIL */
-      1505, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
-      1507, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
+      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 */
@@ -4847,20 +4855,20 @@
        852, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
        851, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
        849, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
-      1695, /* GL_TEXTURE_DEPTH_SIZE */
+      1699, /* GL_TEXTURE_DEPTH_SIZE */
        379, /* GL_DEPTH_TEXTURE_MODE */
-      1660, /* GL_TEXTURE_COMPARE_MODE */
-      1658, /* GL_TEXTURE_COMPARE_FUNC */
+      1664, /* GL_TEXTURE_COMPARE_MODE */
+      1662, /* GL_TEXTURE_COMPARE_FUNC */
        242, /* GL_COMPARE_R_TO_TEXTURE */
       1165, /* GL_POINT_SPRITE */
        296, /* GL_COORD_REPLACE */
       1169, /* GL_POINT_SPRITE_R_MODE_NV */
-      1290, /* GL_QUERY_COUNTER_BITS */
+      1292, /* GL_QUERY_COUNTER_BITS */
        323, /* GL_CURRENT_QUERY */
-      1292, /* GL_QUERY_RESULT */
-      1294, /* GL_QUERY_RESULT_AVAILABLE */
+      1295, /* GL_QUERY_RESULT */
+      1297, /* GL_QUERY_RESULT_AVAILABLE */
        940, /* GL_MAX_VERTEX_ATTRIBS */
-      1837, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
+      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 */
@@ -4868,23 +4876,23 @@
       1236, /* GL_PROGRAM_ERROR_STRING_ARB */
       1238, /* GL_PROGRAM_FORMAT_ASCII_ARB */
       1237, /* GL_PROGRAM_FORMAT_ARB */
-      1745, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+      1749, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
        354, /* GL_DEPTH_BOUNDS_TEST_EXT */
        353, /* GL_DEPTH_BOUNDS_EXT */
         53, /* GL_ARRAY_BUFFER */
        464, /* GL_ELEMENT_ARRAY_BUFFER */
         54, /* GL_ARRAY_BUFFER_BINDING */
        465, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
-      1811, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+      1815, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
       1027, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
        149, /* GL_COLOR_ARRAY_BUFFER_BINDING */
        632, /* GL_INDEX_ARRAY_BUFFER_BINDING */
-      1673, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+      1677, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
        460, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
-      1416, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+      1420, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
        514, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
-      1864, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
-      1833, /* GL_VERTEX_ATTRIB_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 */
@@ -4908,14 +4916,14 @@
        899, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
        895, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
       1260, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
-      1757, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
-      1304, /* GL_READ_ONLY */
-      1872, /* GL_WRITE_ONLY */
-      1306, /* GL_READ_WRITE */
+      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 */
-      1751, /* GL_TIME_ELAPSED_EXT */
+      1755, /* GL_TIME_ELAPSED_EXT */
        808, /* GL_MATRIX0_ARB */
        820, /* GL_MATRIX1_ARB */
        832, /* GL_MATRIX2_ARB */
@@ -4948,12 +4956,12 @@
        831, /* GL_MATRIX29_ARB */
        834, /* GL_MATRIX30_ARB */
        835, /* GL_MATRIX31_ARB */
-      1540, /* GL_STREAM_DRAW */
-      1542, /* GL_STREAM_READ */
-      1538, /* GL_STREAM_COPY */
-      1494, /* GL_STATIC_DRAW */
-      1496, /* GL_STATIC_READ */
-      1492, /* GL_STATIC_COPY */
+      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 */
@@ -4962,30 +4970,30 @@
       1134, /* GL_PIXEL_PACK_BUFFER_BINDING */
       1138, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
        347, /* GL_DEPTH24_STENCIL8 */
-      1741, /* GL_TEXTURE_STENCIL_SIZE */
-      1693, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
+      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 */
-      1531, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+      1535, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
         17, /* GL_ACTIVE_STENCIL_FACE_EXT */
        961, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
-      1397, /* GL_SAMPLES_PASSED */
+      1401, /* GL_SAMPLES_PASSED */
        109, /* GL_BUFFER_SERIALIZED_MODIFY_APPLE */
        104, /* GL_BUFFER_FLUSHING_UNMAP_APPLE */
        537, /* GL_FRAGMENT_SHADER */
-      1857, /* GL_VERTEX_SHADER */
+      1861, /* GL_VERTEX_SHADER */
       1250, /* GL_PROGRAM_OBJECT_ARB */
-      1429, /* GL_SHADER_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 */
-      1431, /* GL_SHADER_TYPE */
+      1435, /* GL_SHADER_TYPE */
        502, /* GL_FLOAT_VEC2 */
        504, /* GL_FLOAT_VEC3 */
        506, /* GL_FLOAT_VEC4 */
@@ -4999,12 +5007,12 @@
        490, /* GL_FLOAT_MAT2 */
        494, /* GL_FLOAT_MAT3 */
        498, /* GL_FLOAT_MAT4 */
-      1388, /* GL_SAMPLER_1D */
-      1390, /* GL_SAMPLER_2D */
-      1392, /* GL_SAMPLER_3D */
-      1393, /* GL_SAMPLER_CUBE */
-      1389, /* GL_SAMPLER_1D_SHADOW */
-      1391, /* GL_SAMPLER_2D_SHADOW */
+      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 */
@@ -5014,16 +5022,16 @@
        345, /* GL_DELETE_STATUS */
        246, /* GL_COMPILE_STATUS */
        715, /* GL_LINK_STATUS */
-      1805, /* GL_VALIDATE_STATUS */
+      1809, /* GL_VALIDATE_STATUS */
        644, /* GL_INFO_LOG_LENGTH */
         56, /* GL_ATTACHED_SHADERS */
         20, /* GL_ACTIVE_UNIFORMS */
         21, /* GL_ACTIVE_UNIFORM_MAX_LENGTH */
-      1430, /* GL_SHADER_SOURCE_LENGTH */
+      1434, /* GL_SHADER_SOURCE_LENGTH */
         15, /* GL_ACTIVE_ATTRIBUTES */
         16, /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */
        539, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
-      1433, /* GL_SHADING_LANGUAGE_VERSION */
+      1437, /* GL_SHADING_LANGUAGE_VERSION */
        322, /* GL_CURRENT_PROGRAM */
       1102, /* GL_PALETTE4_RGB8_OES */
       1104, /* GL_PALETTE4_RGBA8_OES */
@@ -5037,37 +5045,37 @@
       1106, /* GL_PALETTE8_RGB5_A1_OES */
        626, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
        625, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
-      1790, /* GL_UNSIGNED_NORMALIZED */
-      1628, /* GL_TEXTURE_1D_ARRAY_EXT */
+      1794, /* GL_UNSIGNED_NORMALIZED */
+      1632, /* GL_TEXTURE_1D_ARRAY_EXT */
       1272, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
-      1630, /* GL_TEXTURE_2D_ARRAY_EXT */
+      1634, /* GL_TEXTURE_2D_ARRAY_EXT */
       1275, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
-      1636, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
-      1638, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
-      1486, /* GL_SRGB */
-      1487, /* GL_SRGB8 */
-      1489, /* GL_SRGB_ALPHA */
-      1488, /* GL_SRGB8_ALPHA8 */
-      1446, /* GL_SLUMINANCE_ALPHA */
-      1445, /* GL_SLUMINANCE8_ALPHA8 */
-      1443, /* GL_SLUMINANCE */
-      1444, /* GL_SLUMINANCE8 */
+      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 */
       1167, /* GL_POINT_SPRITE_COORD_ORIGIN */
        723, /* GL_LOWER_LEFT */
-      1802, /* GL_UPPER_LEFT */
-      1509, /* GL_STENCIL_BACK_REF */
-      1510, /* GL_STENCIL_BACK_VALUE_MASK */
-      1511, /* GL_STENCIL_BACK_WRITEMASK */
+      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 */
-      1320, /* GL_RENDERBUFFER_BINDING */
-      1300, /* GL_READ_FRAMEBUFFER */
+      1324, /* GL_RENDERBUFFER_BINDING */
+      1304, /* GL_READ_FRAMEBUFFER */
        443, /* GL_DRAW_FRAMEBUFFER */
-      1301, /* GL_READ_FRAMEBUFFER_BINDING */
-      1331, /* GL_RENDERBUFFER_SAMPLES */
+      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 */
@@ -5101,52 +5109,56 @@
        166, /* GL_COLOR_ATTACHMENT14 */
        168, /* GL_COLOR_ATTACHMENT15 */
        349, /* GL_DEPTH_ATTACHMENT */
-      1499, /* GL_STENCIL_ATTACHMENT */
+      1503, /* GL_STENCIL_ATTACHMENT */
        540, /* GL_FRAMEBUFFER */
-      1318, /* GL_RENDERBUFFER */
-      1334, /* GL_RENDERBUFFER_WIDTH */
-      1326, /* GL_RENDERBUFFER_HEIGHT */
-      1328, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
-      1526, /* GL_STENCIL_INDEX_EXT */
-      1518, /* GL_STENCIL_INDEX1 */
-      1522, /* GL_STENCIL_INDEX4 */
-      1524, /* GL_STENCIL_INDEX8 */
-      1519, /* GL_STENCIL_INDEX16 */
-      1330, /* GL_RENDERBUFFER_RED_SIZE */
-      1325, /* GL_RENDERBUFFER_GREEN_SIZE */
-      1322, /* GL_RENDERBUFFER_BLUE_SIZE */
-      1319, /* GL_RENDERBUFFER_ALPHA_SIZE */
-      1323, /* GL_RENDERBUFFER_DEPTH_SIZE */
-      1333, /* GL_RENDERBUFFER_STENCIL_SIZE */
+      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 */
-      1381, /* GL_RGBA_SNORM */
-      1377, /* GL_RGBA8_SNORM */
-      1439, /* GL_SIGNED_NORMALIZED */
+      1385, /* GL_RGBA_SNORM */
+      1381, /* GL_RGBA8_SNORM */
+      1443, /* GL_SIGNED_NORMALIZED */
        923, /* GL_MAX_SERVER_WAIT_TIMEOUT */
       1052, /* GL_OBJECT_TYPE */
-      1547, /* GL_SYNC_CONDITION */
-      1552, /* GL_SYNC_STATUS */
-      1549, /* GL_SYNC_FLAGS */
-      1548, /* GL_SYNC_FENCE */
-      1551, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
-      1778, /* GL_UNSIGNALED */
-      1438, /* GL_SIGNALED */
+      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 */
-      1750, /* GL_TIMEOUT_EXPIRED */
+      1754, /* GL_TIMEOUT_EXPIRED */
        270, /* GL_CONDITION_SATISFIED */
-      1862, /* GL_WAIT_FAILED */
+      1866, /* GL_WAIT_FAILED */
        471, /* GL_EVAL_BIT */
-      1298, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+      1302, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
        717, /* GL_LIST_BIT */
-      1644, /* GL_TEXTURE_BIT */
-      1412, /* GL_SCISSOR_BIT */
+      1648, /* GL_TEXTURE_BIT */
+      1416, /* GL_SCISSOR_BIT */
         29, /* GL_ALL_ATTRIB_BITS */
       1008, /* GL_MULTISAMPLE_BIT */
         30, /* GL_ALL_CLIENT_ATTRIB_BITS */
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 2138bfe..5fc0b1c 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -103,6 +103,7 @@
    { 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_blit",           F(EXT_framebuffer_blit) },
    { OFF, "GL_EXT_framebuffer_multisample",    F(EXT_framebuffer_multisample) },
@@ -166,6 +167,7 @@
    { 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) },
@@ -269,6 +271,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;
@@ -309,6 +312,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;
@@ -523,19 +527,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;
@@ -643,7 +661,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;
@@ -651,8 +668,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;
       }
    }
@@ -668,8 +684,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;
@@ -688,3 +703,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/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
index fe2416d..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)
@@ -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/get.c b/src/mesa/main/get.c
index 3f6b03c..22cf75f 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -132,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);
@@ -210,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;
@@ -1877,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");
@@ -1899,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);
    }
@@ -1967,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);
@@ -2045,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);
@@ -3712,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");
@@ -3734,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);
    }
@@ -3802,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);
@@ -3880,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);
@@ -5547,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");
@@ -5569,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);
    }
@@ -5638,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);
@@ -5716,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);
@@ -7383,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");
@@ -7405,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);
    }
@@ -7434,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 697c4cf..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,
@@ -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);	
@@ -1249,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 6599ed9..e76a790 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/image.c b/src/mesa/main/image.c
index 3b685cb..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"
@@ -3353,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/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 cde2f5f..5227565 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -564,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 */
 
@@ -581,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 */
@@ -1217,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 */
@@ -1899,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;
 };
 
 
@@ -2319,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 */
@@ -2433,6 +2442,7 @@
    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_fog_coord;
    GLboolean EXT_framebuffer_blit;
@@ -2490,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;
@@ -2510,6 +2521,8 @@
    GLboolean S3_s3tc;
    /** The extension string */
    const GLubyte *String;
+   /** Number of supported extensions */
+   GLuint Count;
 };
 
 
@@ -2851,6 +2864,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/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 c80a524..fe2bebd 100644
--- a/src/mesa/main/remap_helper.h
+++ b/src/mesa/main/remap_helper.h
@@ -605,3722 +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]: DeformationMap3dSGIX (dynamic) */
+   /* _mesa_function_pool[10802]: DeformationMap3dSGIX (dynamic) */
    "iddiiddiiddiip\0"
    "glDeformationMap3dSGIX\0"
    "\0"
-   /* _mesa_function_pool[10752]: DepthMask (offset 211) */
+   /* _mesa_function_pool[10841]: DepthMask (offset 211) */
    "i\0"
    "glDepthMask\0"
    "\0"
-   /* _mesa_function_pool[10767]: IsShader (will be remapped) */
+   /* _mesa_function_pool[10856]: IsShader (will be remapped) */
    "i\0"
    "glIsShader\0"
    "\0"
-   /* _mesa_function_pool[10781]: Indexf (offset 46) */
+   /* _mesa_function_pool[10870]: Indexf (offset 46) */
    "f\0"
    "glIndexf\0"
    "\0"
-   /* _mesa_function_pool[10793]: GetImageTransformParameterivHP (dynamic) */
+   /* _mesa_function_pool[10882]: GetImageTransformParameterivHP (dynamic) */
    "iip\0"
    "glGetImageTransformParameterivHP\0"
    "\0"
-   /* _mesa_function_pool[10831]: Indexd (offset 44) */
+   /* _mesa_function_pool[10920]: Indexd (offset 44) */
    "d\0"
    "glIndexd\0"
    "\0"
-   /* _mesa_function_pool[10843]: GetMaterialiv (offset 270) */
+   /* _mesa_function_pool[10932]: GetMaterialiv (offset 270) */
    "iip\0"
    "glGetMaterialiv\0"
    "\0"
-   /* _mesa_function_pool[10864]: StencilOp (offset 244) */
+   /* _mesa_function_pool[10953]: StencilOp (offset 244) */
    "iii\0"
    "glStencilOp\0"
    "\0"
-   /* _mesa_function_pool[10881]: WindowPos4ivMESA (will be remapped) */
+   /* _mesa_function_pool[10970]: WindowPos4ivMESA (will be remapped) */
    "p\0"
    "glWindowPos4ivMESA\0"
    "\0"
-   /* _mesa_function_pool[10903]: MultiTexCoord3svARB (offset 399) */
+   /* _mesa_function_pool[10992]: MultiTexCoord3svARB (offset 399) */
    "ip\0"
    "glMultiTexCoord3sv\0"
    "glMultiTexCoord3svARB\0"
    "\0"
-   /* _mesa_function_pool[10948]: TexEnvfv (offset 185) */
+   /* _mesa_function_pool[11037]: TexEnvfv (offset 185) */
    "iip\0"
    "glTexEnvfv\0"
    "\0"
-   /* _mesa_function_pool[10964]: MultiTexCoord4iARB (offset 404) */
+   /* _mesa_function_pool[11053]: MultiTexCoord4iARB (offset 404) */
    "iiiii\0"
    "glMultiTexCoord4i\0"
    "glMultiTexCoord4iARB\0"
    "\0"
-   /* _mesa_function_pool[11010]: Indexs (offset 50) */
+   /* _mesa_function_pool[11099]: Indexs (offset 50) */
    "i\0"
    "glIndexs\0"
    "\0"
-   /* _mesa_function_pool[11022]: Binormal3ivEXT (dynamic) */
+   /* _mesa_function_pool[11111]: Binormal3ivEXT (dynamic) */
    "p\0"
    "glBinormal3ivEXT\0"
    "\0"
-   /* _mesa_function_pool[11042]: ResizeBuffersMESA (will be remapped) */
+   /* _mesa_function_pool[11131]: ResizeBuffersMESA (will be remapped) */
    "\0"
    "glResizeBuffersMESA\0"
    "\0"
-   /* _mesa_function_pool[11064]: GetUniformivARB (will be remapped) */
+   /* _mesa_function_pool[11153]: GetUniformivARB (will be remapped) */
    "iip\0"
    "glGetUniformiv\0"
    "glGetUniformivARB\0"
    "\0"
-   /* _mesa_function_pool[11102]: PixelTexGenParameteriSGIS (will be remapped) */
+   /* _mesa_function_pool[11191]: PixelTexGenParameteriSGIS (will be remapped) */
    "ii\0"
    "glPixelTexGenParameteriSGIS\0"
    "\0"
-   /* _mesa_function_pool[11134]: VertexPointervINTEL (dynamic) */
+   /* _mesa_function_pool[11223]: VertexPointervINTEL (dynamic) */
    "iip\0"
    "glVertexPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[11161]: Vertex2i (offset 130) */
+   /* _mesa_function_pool[11250]: Vertex2i (offset 130) */
    "ii\0"
    "glVertex2i\0"
    "\0"
-   /* _mesa_function_pool[11176]: LoadMatrixf (offset 291) */
+   /* _mesa_function_pool[11265]: LoadMatrixf (offset 291) */
    "p\0"
    "glLoadMatrixf\0"
    "\0"
-   /* _mesa_function_pool[11193]: Vertex2f (offset 128) */
+   /* _mesa_function_pool[11282]: Vertex2f (offset 128) */
    "ff\0"
    "glVertex2f\0"
    "\0"
-   /* _mesa_function_pool[11208]: ReplacementCodeuiColor4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[11297]: ReplacementCodeuiColor4fNormal3fVertex3fvSUN (dynamic) */
    "pppp\0"
    "glReplacementCodeuiColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[11261]: Color4bv (offset 26) */
+   /* _mesa_function_pool[11350]: Color4bv (offset 26) */
    "p\0"
    "glColor4bv\0"
    "\0"
-   /* _mesa_function_pool[11275]: VertexPointer (offset 321) */
+   /* _mesa_function_pool[11364]: VertexPointer (offset 321) */
    "iiip\0"
    "glVertexPointer\0"
    "\0"
-   /* _mesa_function_pool[11297]: SecondaryColor3uiEXT (will be remapped) */
+   /* _mesa_function_pool[11386]: SecondaryColor3uiEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3ui\0"
    "glSecondaryColor3uiEXT\0"
    "\0"
-   /* _mesa_function_pool[11345]: StartInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[11434]: StartInstrumentsSGIX (dynamic) */
    "\0"
    "glStartInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[11370]: SecondaryColor3usvEXT (will be remapped) */
+   /* _mesa_function_pool[11459]: SecondaryColor3usvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3usv\0"
    "glSecondaryColor3usvEXT\0"
    "\0"
-   /* _mesa_function_pool[11418]: VertexAttrib2fvNV (will be remapped) */
+   /* _mesa_function_pool[11507]: VertexAttrib2fvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib2fvNV\0"
    "\0"
-   /* _mesa_function_pool[11442]: ProgramLocalParameter4dvARB (will be remapped) */
+   /* _mesa_function_pool[11531]: ProgramLocalParameter4dvARB (will be remapped) */
    "iip\0"
    "glProgramLocalParameter4dvARB\0"
    "\0"
-   /* _mesa_function_pool[11477]: DeleteLists (offset 4) */
+   /* _mesa_function_pool[11566]: DeleteLists (offset 4) */
    "ii\0"
    "glDeleteLists\0"
    "\0"
-   /* _mesa_function_pool[11495]: LogicOp (offset 242) */
+   /* _mesa_function_pool[11584]: LogicOp (offset 242) */
    "i\0"
    "glLogicOp\0"
    "\0"
-   /* _mesa_function_pool[11508]: MatrixIndexuivARB (dynamic) */
+   /* _mesa_function_pool[11597]: MatrixIndexuivARB (dynamic) */
    "ip\0"
    "glMatrixIndexuivARB\0"
    "\0"
-   /* _mesa_function_pool[11532]: Vertex2s (offset 132) */
+   /* _mesa_function_pool[11621]: Vertex2s (offset 132) */
    "ii\0"
    "glVertex2s\0"
    "\0"
-   /* _mesa_function_pool[11547]: RenderbufferStorageMultisample (will be remapped) */
+   /* _mesa_function_pool[11636]: RenderbufferStorageMultisample (will be remapped) */
    "iiiii\0"
    "glRenderbufferStorageMultisample\0"
    "glRenderbufferStorageMultisampleEXT\0"
    "\0"
-   /* _mesa_function_pool[11623]: TexCoord4fv (offset 121) */
+   /* _mesa_function_pool[11712]: TexCoord4fv (offset 121) */
    "p\0"
    "glTexCoord4fv\0"
    "\0"
-   /* _mesa_function_pool[11640]: Tangent3sEXT (dynamic) */
+   /* _mesa_function_pool[11729]: Tangent3sEXT (dynamic) */
    "iii\0"
    "glTangent3sEXT\0"
    "\0"
-   /* _mesa_function_pool[11660]: GlobalAlphaFactorfSUN (dynamic) */
+   /* _mesa_function_pool[11749]: GlobalAlphaFactorfSUN (dynamic) */
    "f\0"
    "glGlobalAlphaFactorfSUN\0"
    "\0"
-   /* _mesa_function_pool[11687]: MultiTexCoord3iARB (offset 396) */
+   /* _mesa_function_pool[11776]: MultiTexCoord3iARB (offset 396) */
    "iiii\0"
    "glMultiTexCoord3i\0"
    "glMultiTexCoord3iARB\0"
    "\0"
-   /* _mesa_function_pool[11732]: IsProgram (will be remapped) */
+   /* _mesa_function_pool[11821]: IsProgram (will be remapped) */
    "i\0"
    "glIsProgram\0"
    "\0"
-   /* _mesa_function_pool[11747]: TexCoordPointerListIBM (dynamic) */
+   /* _mesa_function_pool[11836]: TexCoordPointerListIBM (dynamic) */
    "iiipi\0"
    "glTexCoordPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[11779]: GlobalAlphaFactorusSUN (dynamic) */
+   /* _mesa_function_pool[11868]: GlobalAlphaFactorusSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactorusSUN\0"
    "\0"
-   /* _mesa_function_pool[11807]: VertexAttrib2dvNV (will be remapped) */
+   /* _mesa_function_pool[11896]: VertexAttrib2dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib2dvNV\0"
    "\0"
-   /* _mesa_function_pool[11831]: FramebufferRenderbufferEXT (will be remapped) */
+   /* _mesa_function_pool[11920]: FramebufferRenderbufferEXT (will be remapped) */
    "iiii\0"
    "glFramebufferRenderbuffer\0"
    "glFramebufferRenderbufferEXT\0"
    "\0"
-   /* _mesa_function_pool[11892]: VertexAttrib1dvNV (will be remapped) */
+   /* _mesa_function_pool[11981]: VertexAttrib1dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib1dvNV\0"
    "\0"
-   /* _mesa_function_pool[11916]: GenTextures (offset 328) */
+   /* _mesa_function_pool[12005]: GenTextures (offset 328) */
    "ip\0"
    "glGenTextures\0"
    "glGenTexturesEXT\0"
    "\0"
-   /* _mesa_function_pool[11951]: SetFenceNV (will be remapped) */
+   /* _mesa_function_pool[12040]: SetFenceNV (will be remapped) */
    "ii\0"
    "glSetFenceNV\0"
    "\0"
-   /* _mesa_function_pool[11968]: FramebufferTexture1DEXT (will be remapped) */
+   /* _mesa_function_pool[12057]: FramebufferTexture1DEXT (will be remapped) */
    "iiiii\0"
    "glFramebufferTexture1D\0"
    "glFramebufferTexture1DEXT\0"
    "\0"
-   /* _mesa_function_pool[12024]: GetCombinerOutputParameterivNV (will be remapped) */
+   /* _mesa_function_pool[12113]: GetCombinerOutputParameterivNV (will be remapped) */
    "iiip\0"
    "glGetCombinerOutputParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[12063]: PixelTexGenParameterivSGIS (will be remapped) */
+   /* _mesa_function_pool[12152]: PixelTexGenParameterivSGIS (will be remapped) */
    "ip\0"
    "glPixelTexGenParameterivSGIS\0"
    "\0"
-   /* _mesa_function_pool[12096]: TextureNormalEXT (dynamic) */
+   /* _mesa_function_pool[12185]: TextureNormalEXT (dynamic) */
    "i\0"
    "glTextureNormalEXT\0"
    "\0"
-   /* _mesa_function_pool[12118]: IndexPointerListIBM (dynamic) */
+   /* _mesa_function_pool[12207]: IndexPointerListIBM (dynamic) */
    "iipi\0"
    "glIndexPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[12146]: WeightfvARB (dynamic) */
+   /* _mesa_function_pool[12235]: WeightfvARB (dynamic) */
    "ip\0"
    "glWeightfvARB\0"
    "\0"
-   /* _mesa_function_pool[12164]: RasterPos2sv (offset 69) */
+   /* _mesa_function_pool[12253]: RasterPos2sv (offset 69) */
    "p\0"
    "glRasterPos2sv\0"
    "\0"
-   /* _mesa_function_pool[12182]: Color4ubv (offset 36) */
+   /* _mesa_function_pool[12271]: Color4ubv (offset 36) */
    "p\0"
    "glColor4ubv\0"
    "\0"
-   /* _mesa_function_pool[12197]: DrawBuffer (offset 202) */
+   /* _mesa_function_pool[12286]: DrawBuffer (offset 202) */
    "i\0"
    "glDrawBuffer\0"
    "\0"
-   /* _mesa_function_pool[12213]: TexCoord2fv (offset 105) */
+   /* _mesa_function_pool[12302]: TexCoord2fv (offset 105) */
    "p\0"
    "glTexCoord2fv\0"
    "\0"
-   /* _mesa_function_pool[12230]: WindowPos4fMESA (will be remapped) */
+   /* _mesa_function_pool[12319]: WindowPos4fMESA (will be remapped) */
    "ffff\0"
    "glWindowPos4fMESA\0"
    "\0"
-   /* _mesa_function_pool[12254]: TexCoord1sv (offset 101) */
+   /* _mesa_function_pool[12343]: TexCoord1sv (offset 101) */
    "p\0"
    "glTexCoord1sv\0"
    "\0"
-   /* _mesa_function_pool[12271]: WindowPos3dvMESA (will be remapped) */
+   /* _mesa_function_pool[12360]: WindowPos3dvMESA (will be remapped) */
    "p\0"
    "glWindowPos3dv\0"
    "glWindowPos3dvARB\0"
    "glWindowPos3dvMESA\0"
    "\0"
-   /* _mesa_function_pool[12326]: DepthFunc (offset 245) */
+   /* _mesa_function_pool[12415]: DepthFunc (offset 245) */
    "i\0"
    "glDepthFunc\0"
    "\0"
-   /* _mesa_function_pool[12341]: PixelMapusv (offset 253) */
+   /* _mesa_function_pool[12430]: PixelMapusv (offset 253) */
    "iip\0"
    "glPixelMapusv\0"
    "\0"
-   /* _mesa_function_pool[12360]: GetQueryObjecti64vEXT (will be remapped) */
+   /* _mesa_function_pool[12449]: GetQueryObjecti64vEXT (will be remapped) */
    "iip\0"
    "glGetQueryObjecti64vEXT\0"
    "\0"
-   /* _mesa_function_pool[12389]: MultiTexCoord1dARB (offset 376) */
+   /* _mesa_function_pool[12478]: MultiTexCoord1dARB (offset 376) */
    "id\0"
    "glMultiTexCoord1d\0"
    "glMultiTexCoord1dARB\0"
    "\0"
-   /* _mesa_function_pool[12432]: PointParameterivNV (will be remapped) */
+   /* _mesa_function_pool[12521]: PointParameterivNV (will be remapped) */
    "ip\0"
    "glPointParameteriv\0"
    "glPointParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[12476]: BlendFunc (offset 241) */
+   /* _mesa_function_pool[12565]: BlendFunc (offset 241) */
    "ii\0"
    "glBlendFunc\0"
    "\0"
-   /* _mesa_function_pool[12492]: Uniform2fvARB (will be remapped) */
+   /* _mesa_function_pool[12581]: Uniform2fvARB (will be remapped) */
    "iip\0"
    "glUniform2fv\0"
    "glUniform2fvARB\0"
    "\0"
-   /* _mesa_function_pool[12526]: BufferParameteriAPPLE (will be remapped) */
+   /* _mesa_function_pool[12615]: BufferParameteriAPPLE (will be remapped) */
    "iii\0"
    "glBufferParameteriAPPLE\0"
    "\0"
-   /* _mesa_function_pool[12555]: MultiTexCoord3dvARB (offset 393) */
+   /* _mesa_function_pool[12644]: MultiTexCoord3dvARB (offset 393) */
    "ip\0"
    "glMultiTexCoord3dv\0"
    "glMultiTexCoord3dvARB\0"
    "\0"
-   /* _mesa_function_pool[12600]: ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[12689]: ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (dynamic) */
    "pppp\0"
    "glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[12656]: DeleteObjectARB (will be remapped) */
+   /* _mesa_function_pool[12745]: DeleteObjectARB (will be remapped) */
    "i\0"
    "glDeleteObjectARB\0"
    "\0"
-   /* _mesa_function_pool[12677]: MatrixIndexPointerARB (dynamic) */
+   /* _mesa_function_pool[12766]: MatrixIndexPointerARB (dynamic) */
    "iiip\0"
    "glMatrixIndexPointerARB\0"
    "\0"
-   /* _mesa_function_pool[12707]: ProgramNamedParameter4dvNV (will be remapped) */
+   /* _mesa_function_pool[12796]: ProgramNamedParameter4dvNV (will be remapped) */
    "iipp\0"
    "glProgramNamedParameter4dvNV\0"
    "\0"
-   /* _mesa_function_pool[12742]: Tangent3fvEXT (dynamic) */
+   /* _mesa_function_pool[12831]: Tangent3fvEXT (dynamic) */
    "p\0"
    "glTangent3fvEXT\0"
    "\0"
-   /* _mesa_function_pool[12761]: Flush (offset 217) */
+   /* _mesa_function_pool[12850]: Flush (offset 217) */
    "\0"
    "glFlush\0"
    "\0"
-   /* _mesa_function_pool[12771]: Color4uiv (offset 38) */
+   /* _mesa_function_pool[12860]: Color4uiv (offset 38) */
    "p\0"
    "glColor4uiv\0"
    "\0"
-   /* _mesa_function_pool[12786]: GenVertexArrays (will be remapped) */
+   /* _mesa_function_pool[12875]: GenVertexArrays (will be remapped) */
    "ip\0"
    "glGenVertexArrays\0"
    "\0"
-   /* _mesa_function_pool[12808]: RasterPos3sv (offset 77) */
+   /* _mesa_function_pool[12897]: RasterPos3sv (offset 77) */
    "p\0"
    "glRasterPos3sv\0"
    "\0"
-   /* _mesa_function_pool[12826]: BindFramebufferEXT (will be remapped) */
+   /* _mesa_function_pool[12915]: BindFramebufferEXT (will be remapped) */
    "ii\0"
    "glBindFramebuffer\0"
    "glBindFramebufferEXT\0"
    "\0"
-   /* _mesa_function_pool[12869]: ReferencePlaneSGIX (dynamic) */
+   /* _mesa_function_pool[12958]: ReferencePlaneSGIX (dynamic) */
    "p\0"
    "glReferencePlaneSGIX\0"
    "\0"
-   /* _mesa_function_pool[12893]: PushAttrib (offset 219) */
+   /* _mesa_function_pool[12982]: PushAttrib (offset 219) */
    "i\0"
    "glPushAttrib\0"
    "\0"
-   /* _mesa_function_pool[12909]: RasterPos2i (offset 66) */
+   /* _mesa_function_pool[12998]: RasterPos2i (offset 66) */
    "ii\0"
    "glRasterPos2i\0"
    "\0"
-   /* _mesa_function_pool[12927]: ValidateProgramARB (will be remapped) */
+   /* _mesa_function_pool[13016]: ValidateProgramARB (will be remapped) */
    "i\0"
    "glValidateProgram\0"
    "glValidateProgramARB\0"
    "\0"
-   /* _mesa_function_pool[12969]: TexParameteriv (offset 181) */
+   /* _mesa_function_pool[13058]: TexParameteriv (offset 181) */
    "iip\0"
    "glTexParameteriv\0"
    "\0"
-   /* _mesa_function_pool[12991]: UnlockArraysEXT (will be remapped) */
+   /* _mesa_function_pool[13080]: UnlockArraysEXT (will be remapped) */
    "\0"
    "glUnlockArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[13011]: TexCoord2fColor3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[13100]: TexCoord2fColor3fVertex3fSUN (dynamic) */
    "ffffffff\0"
    "glTexCoord2fColor3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[13052]: WindowPos3fvMESA (will be remapped) */
+   /* _mesa_function_pool[13141]: WindowPos3fvMESA (will be remapped) */
    "p\0"
    "glWindowPos3fv\0"
    "glWindowPos3fvARB\0"
    "glWindowPos3fvMESA\0"
    "\0"
-   /* _mesa_function_pool[13107]: RasterPos2f (offset 64) */
+   /* _mesa_function_pool[13196]: RasterPos2f (offset 64) */
    "ff\0"
    "glRasterPos2f\0"
    "\0"
-   /* _mesa_function_pool[13125]: VertexAttrib1svNV (will be remapped) */
+   /* _mesa_function_pool[13214]: VertexAttrib1svNV (will be remapped) */
    "ip\0"
    "glVertexAttrib1svNV\0"
    "\0"
-   /* _mesa_function_pool[13149]: RasterPos2d (offset 62) */
+   /* _mesa_function_pool[13238]: RasterPos2d (offset 62) */
    "dd\0"
    "glRasterPos2d\0"
    "\0"
-   /* _mesa_function_pool[13167]: RasterPos3fv (offset 73) */
+   /* _mesa_function_pool[13256]: RasterPos3fv (offset 73) */
    "p\0"
    "glRasterPos3fv\0"
    "\0"
-   /* _mesa_function_pool[13185]: CopyTexSubImage3D (offset 373) */
+   /* _mesa_function_pool[13274]: CopyTexSubImage3D (offset 373) */
    "iiiiiiiii\0"
    "glCopyTexSubImage3D\0"
    "glCopyTexSubImage3DEXT\0"
    "\0"
-   /* _mesa_function_pool[13239]: VertexAttrib2dARB (will be remapped) */
+   /* _mesa_function_pool[13328]: VertexAttrib2dARB (will be remapped) */
    "idd\0"
    "glVertexAttrib2d\0"
    "glVertexAttrib2dARB\0"
    "\0"
-   /* _mesa_function_pool[13281]: Color4ub (offset 35) */
+   /* _mesa_function_pool[13370]: Color4ub (offset 35) */
    "iiii\0"
    "glColor4ub\0"
    "\0"
-   /* _mesa_function_pool[13298]: GetInteger64v (will be remapped) */
+   /* _mesa_function_pool[13387]: GetInteger64v (will be remapped) */
    "ip\0"
    "glGetInteger64v\0"
    "\0"
-   /* _mesa_function_pool[13318]: TextureColorMaskSGIS (dynamic) */
+   /* _mesa_function_pool[13407]: TextureColorMaskSGIS (dynamic) */
    "iiii\0"
    "glTextureColorMaskSGIS\0"
    "\0"
-   /* _mesa_function_pool[13347]: RasterPos2s (offset 68) */
+   /* _mesa_function_pool[13436]: RasterPos2s (offset 68) */
    "ii\0"
    "glRasterPos2s\0"
    "\0"
-   /* _mesa_function_pool[13365]: GetColorTable (offset 343) */
+   /* _mesa_function_pool[13454]: GetColorTable (offset 343) */
    "iiip\0"
    "glGetColorTable\0"
    "glGetColorTableSGI\0"
    "glGetColorTableEXT\0"
    "\0"
-   /* _mesa_function_pool[13425]: SelectBuffer (offset 195) */
+   /* _mesa_function_pool[13514]: SelectBuffer (offset 195) */
    "ip\0"
    "glSelectBuffer\0"
    "\0"
-   /* _mesa_function_pool[13444]: Indexiv (offset 49) */
+   /* _mesa_function_pool[13533]: Indexiv (offset 49) */
    "p\0"
    "glIndexiv\0"
    "\0"
-   /* _mesa_function_pool[13457]: TexCoord3i (offset 114) */
+   /* _mesa_function_pool[13546]: TexCoord3i (offset 114) */
    "iii\0"
    "glTexCoord3i\0"
    "\0"
-   /* _mesa_function_pool[13475]: CopyColorTable (offset 342) */
+   /* _mesa_function_pool[13564]: CopyColorTable (offset 342) */
    "iiiii\0"
    "glCopyColorTable\0"
    "glCopyColorTableSGI\0"
    "\0"
-   /* _mesa_function_pool[13519]: GetHistogramParameterfv (offset 362) */
+   /* _mesa_function_pool[13608]: GetHistogramParameterfv (offset 362) */
    "iip\0"
    "glGetHistogramParameterfv\0"
    "glGetHistogramParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[13579]: Frustum (offset 289) */
+   /* _mesa_function_pool[13668]: Frustum (offset 289) */
    "dddddd\0"
    "glFrustum\0"
    "\0"
-   /* _mesa_function_pool[13597]: GetString (offset 275) */
+   /* _mesa_function_pool[13686]: GetString (offset 275) */
    "i\0"
    "glGetString\0"
    "\0"
-   /* _mesa_function_pool[13612]: ColorPointervINTEL (dynamic) */
+   /* _mesa_function_pool[13701]: ColorPointervINTEL (dynamic) */
    "iip\0"
    "glColorPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[13638]: TexEnvf (offset 184) */
+   /* _mesa_function_pool[13727]: TexEnvf (offset 184) */
    "iif\0"
    "glTexEnvf\0"
    "\0"
-   /* _mesa_function_pool[13653]: TexCoord3d (offset 110) */
+   /* _mesa_function_pool[13742]: TexCoord3d (offset 110) */
    "ddd\0"
    "glTexCoord3d\0"
    "\0"
-   /* _mesa_function_pool[13671]: AlphaFragmentOp1ATI (will be remapped) */
+   /* _mesa_function_pool[13760]: AlphaFragmentOp1ATI (will be remapped) */
    "iiiiii\0"
    "glAlphaFragmentOp1ATI\0"
    "\0"
-   /* _mesa_function_pool[13701]: TexCoord3f (offset 112) */
+   /* _mesa_function_pool[13790]: TexCoord3f (offset 112) */
    "fff\0"
    "glTexCoord3f\0"
    "\0"
-   /* _mesa_function_pool[13719]: MultiTexCoord3ivARB (offset 397) */
+   /* _mesa_function_pool[13808]: MultiTexCoord3ivARB (offset 397) */
    "ip\0"
    "glMultiTexCoord3iv\0"
    "glMultiTexCoord3ivARB\0"
    "\0"
-   /* _mesa_function_pool[13764]: MultiTexCoord2sARB (offset 390) */
+   /* _mesa_function_pool[13853]: MultiTexCoord2sARB (offset 390) */
    "iii\0"
    "glMultiTexCoord2s\0"
    "glMultiTexCoord2sARB\0"
    "\0"
-   /* _mesa_function_pool[13808]: VertexAttrib1dvARB (will be remapped) */
+   /* _mesa_function_pool[13897]: VertexAttrib1dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib1dv\0"
    "glVertexAttrib1dvARB\0"
    "\0"
-   /* _mesa_function_pool[13851]: DeleteTextures (offset 327) */
+   /* _mesa_function_pool[13940]: DeleteTextures (offset 327) */
    "ip\0"
    "glDeleteTextures\0"
    "glDeleteTexturesEXT\0"
    "\0"
-   /* _mesa_function_pool[13892]: TexCoordPointerEXT (will be remapped) */
+   /* _mesa_function_pool[13981]: TexCoordPointerEXT (will be remapped) */
    "iiiip\0"
    "glTexCoordPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[13920]: TexSubImage4DSGIS (dynamic) */
+   /* _mesa_function_pool[14009]: TexSubImage4DSGIS (dynamic) */
    "iiiiiiiiiiiip\0"
    "glTexSubImage4DSGIS\0"
    "\0"
-   /* _mesa_function_pool[13955]: TexCoord3s (offset 116) */
+   /* _mesa_function_pool[14044]: TexCoord3s (offset 116) */
    "iii\0"
    "glTexCoord3s\0"
    "\0"
-   /* _mesa_function_pool[13973]: GetTexLevelParameteriv (offset 285) */
+   /* _mesa_function_pool[14062]: GetTexLevelParameteriv (offset 285) */
    "iiip\0"
    "glGetTexLevelParameteriv\0"
    "\0"
-   /* _mesa_function_pool[14004]: CombinerStageParameterfvNV (dynamic) */
+   /* _mesa_function_pool[14093]: CombinerStageParameterfvNV (dynamic) */
    "iip\0"
    "glCombinerStageParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[14038]: StopInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[14127]: StopInstrumentsSGIX (dynamic) */
    "i\0"
    "glStopInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[14063]: TexCoord4fColor4fNormal3fVertex4fSUN (dynamic) */
+   /* _mesa_function_pool[14152]: TexCoord4fColor4fNormal3fVertex4fSUN (dynamic) */
    "fffffffffffffff\0"
    "glTexCoord4fColor4fNormal3fVertex4fSUN\0"
    "\0"
-   /* _mesa_function_pool[14119]: ClearAccum (offset 204) */
+   /* _mesa_function_pool[14208]: ClearAccum (offset 204) */
    "ffff\0"
    "glClearAccum\0"
    "\0"
-   /* _mesa_function_pool[14138]: DeformSGIX (dynamic) */
+   /* _mesa_function_pool[14227]: DeformSGIX (dynamic) */
    "i\0"
    "glDeformSGIX\0"
    "\0"
-   /* _mesa_function_pool[14154]: GetVertexAttribfvARB (will be remapped) */
+   /* _mesa_function_pool[14243]: GetVertexAttribfvARB (will be remapped) */
    "iip\0"
    "glGetVertexAttribfv\0"
    "glGetVertexAttribfvARB\0"
    "\0"
-   /* _mesa_function_pool[14202]: SecondaryColor3ivEXT (will be remapped) */
+   /* _mesa_function_pool[14291]: SecondaryColor3ivEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3iv\0"
    "glSecondaryColor3ivEXT\0"
    "\0"
-   /* _mesa_function_pool[14248]: TexCoord4iv (offset 123) */
+   /* _mesa_function_pool[14337]: TexCoord4iv (offset 123) */
    "p\0"
    "glTexCoord4iv\0"
    "\0"
-   /* _mesa_function_pool[14265]: UniformMatrix4x2fv (will be remapped) */
+   /* _mesa_function_pool[14354]: UniformMatrix4x2fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix4x2fv\0"
    "\0"
-   /* _mesa_function_pool[14292]: GetDetailTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[14381]: GetDetailTexFuncSGIS (dynamic) */
    "ip\0"
    "glGetDetailTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[14319]: GetCombinerStageParameterfvNV (dynamic) */
+   /* _mesa_function_pool[14408]: GetCombinerStageParameterfvNV (dynamic) */
    "iip\0"
    "glGetCombinerStageParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[14356]: PolygonOffset (offset 319) */
+   /* _mesa_function_pool[14445]: PolygonOffset (offset 319) */
    "ff\0"
    "glPolygonOffset\0"
    "\0"
-   /* _mesa_function_pool[14376]: BindVertexArray (will be remapped) */
+   /* _mesa_function_pool[14465]: BindVertexArray (will be remapped) */
    "i\0"
    "glBindVertexArray\0"
    "\0"
-   /* _mesa_function_pool[14397]: Color4ubVertex2fvSUN (dynamic) */
+   /* _mesa_function_pool[14486]: Color4ubVertex2fvSUN (dynamic) */
    "pp\0"
    "glColor4ubVertex2fvSUN\0"
    "\0"
-   /* _mesa_function_pool[14424]: Rectd (offset 86) */
+   /* _mesa_function_pool[14513]: Rectd (offset 86) */
    "dddd\0"
    "glRectd\0"
    "\0"
-   /* _mesa_function_pool[14438]: TexFilterFuncSGIS (dynamic) */
+   /* _mesa_function_pool[14527]: TexFilterFuncSGIS (dynamic) */
    "iiip\0"
    "glTexFilterFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[14464]: SampleMaskSGIS (will be remapped) */
+   /* _mesa_function_pool[14553]: SampleMaskSGIS (will be remapped) */
    "fi\0"
    "glSampleMaskSGIS\0"
    "glSampleMaskEXT\0"
    "\0"
-   /* _mesa_function_pool[14501]: GetAttribLocationARB (will be remapped) */
+   /* _mesa_function_pool[14590]: GetAttribLocationARB (will be remapped) */
    "ip\0"
    "glGetAttribLocation\0"
    "glGetAttribLocationARB\0"
    "\0"
-   /* _mesa_function_pool[14548]: RasterPos3i (offset 74) */
+   /* _mesa_function_pool[14637]: RasterPos3i (offset 74) */
    "iii\0"
    "glRasterPos3i\0"
    "\0"
-   /* _mesa_function_pool[14567]: VertexAttrib4ubvARB (will be remapped) */
+   /* _mesa_function_pool[14656]: VertexAttrib4ubvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4ubv\0"
    "glVertexAttrib4ubvARB\0"
    "\0"
-   /* _mesa_function_pool[14612]: DetailTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[14701]: DetailTexFuncSGIS (dynamic) */
    "iip\0"
    "glDetailTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[14637]: Normal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[14726]: Normal3fVertex3fSUN (dynamic) */
    "ffffff\0"
    "glNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[14667]: CopyTexImage2D (offset 324) */
+   /* _mesa_function_pool[14756]: CopyTexImage2D (offset 324) */
    "iiiiiiii\0"
    "glCopyTexImage2D\0"
    "glCopyTexImage2DEXT\0"
    "\0"
-   /* _mesa_function_pool[14714]: GetBufferPointervARB (will be remapped) */
+   /* _mesa_function_pool[14803]: GetBufferPointervARB (will be remapped) */
    "iip\0"
    "glGetBufferPointerv\0"
    "glGetBufferPointervARB\0"
    "\0"
-   /* _mesa_function_pool[14762]: ProgramEnvParameter4fARB (will be remapped) */
+   /* _mesa_function_pool[14851]: ProgramEnvParameter4fARB (will be remapped) */
    "iiffff\0"
    "glProgramEnvParameter4fARB\0"
    "glProgramParameter4fNV\0"
    "\0"
-   /* _mesa_function_pool[14820]: Uniform3ivARB (will be remapped) */
+   /* _mesa_function_pool[14909]: Uniform3ivARB (will be remapped) */
    "iip\0"
    "glUniform3iv\0"
    "glUniform3ivARB\0"
    "\0"
-   /* _mesa_function_pool[14854]: Lightfv (offset 160) */
+   /* _mesa_function_pool[14943]: Lightfv (offset 160) */
    "iip\0"
    "glLightfv\0"
    "\0"
-   /* _mesa_function_pool[14869]: ClearDepth (offset 208) */
+   /* _mesa_function_pool[14958]: ClearDepth (offset 208) */
    "d\0"
    "glClearDepth\0"
    "\0"
-   /* _mesa_function_pool[14885]: GetFenceivNV (will be remapped) */
+   /* _mesa_function_pool[14974]: GetFenceivNV (will be remapped) */
    "iip\0"
    "glGetFenceivNV\0"
    "\0"
-   /* _mesa_function_pool[14905]: WindowPos4dvMESA (will be remapped) */
+   /* _mesa_function_pool[14994]: WindowPos4dvMESA (will be remapped) */
    "p\0"
    "glWindowPos4dvMESA\0"
    "\0"
-   /* _mesa_function_pool[14927]: ColorSubTable (offset 346) */
+   /* _mesa_function_pool[15016]: ColorSubTable (offset 346) */
    "iiiiip\0"
    "glColorSubTable\0"
    "glColorSubTableEXT\0"
    "\0"
-   /* _mesa_function_pool[14970]: Color4fv (offset 30) */
+   /* _mesa_function_pool[15059]: Color4fv (offset 30) */
    "p\0"
    "glColor4fv\0"
    "\0"
-   /* _mesa_function_pool[14984]: MultiTexCoord4ivARB (offset 405) */
+   /* _mesa_function_pool[15073]: MultiTexCoord4ivARB (offset 405) */
    "ip\0"
    "glMultiTexCoord4iv\0"
    "glMultiTexCoord4ivARB\0"
    "\0"
-   /* _mesa_function_pool[15029]: ProgramLocalParameters4fvEXT (will be remapped) */
+   /* _mesa_function_pool[15118]: ProgramLocalParameters4fvEXT (will be remapped) */
    "iiip\0"
    "glProgramLocalParameters4fvEXT\0"
    "\0"
-   /* _mesa_function_pool[15066]: ColorPointer (offset 308) */
+   /* _mesa_function_pool[15155]: ColorPointer (offset 308) */
    "iiip\0"
    "glColorPointer\0"
    "\0"
-   /* _mesa_function_pool[15087]: Rects (offset 92) */
+   /* _mesa_function_pool[15176]: Rects (offset 92) */
    "iiii\0"
    "glRects\0"
    "\0"
-   /* _mesa_function_pool[15101]: GetMapAttribParameterfvNV (dynamic) */
+   /* _mesa_function_pool[15190]: GetMapAttribParameterfvNV (dynamic) */
    "iiip\0"
    "glGetMapAttribParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[15135]: Lightiv (offset 162) */
+   /* _mesa_function_pool[15224]: Lightiv (offset 162) */
    "iip\0"
    "glLightiv\0"
    "\0"
-   /* _mesa_function_pool[15150]: VertexAttrib4sARB (will be remapped) */
+   /* _mesa_function_pool[15239]: VertexAttrib4sARB (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4s\0"
    "glVertexAttrib4sARB\0"
    "\0"
-   /* _mesa_function_pool[15194]: GetQueryObjectuivARB (will be remapped) */
+   /* _mesa_function_pool[15283]: GetQueryObjectuivARB (will be remapped) */
    "iip\0"
    "glGetQueryObjectuiv\0"
    "glGetQueryObjectuivARB\0"
    "\0"
-   /* _mesa_function_pool[15242]: GetTexParameteriv (offset 283) */
+   /* _mesa_function_pool[15331]: GetTexParameteriv (offset 283) */
    "iip\0"
    "glGetTexParameteriv\0"
    "\0"
-   /* _mesa_function_pool[15267]: MapParameterivNV (dynamic) */
+   /* _mesa_function_pool[15356]: MapParameterivNV (dynamic) */
    "iip\0"
    "glMapParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[15291]: GenRenderbuffersEXT (will be remapped) */
+   /* _mesa_function_pool[15380]: GenRenderbuffersEXT (will be remapped) */
    "ip\0"
    "glGenRenderbuffers\0"
    "glGenRenderbuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[15336]: VertexAttrib2dvARB (will be remapped) */
+   /* _mesa_function_pool[15425]: VertexAttrib2dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib2dv\0"
    "glVertexAttrib2dvARB\0"
    "\0"
-   /* _mesa_function_pool[15379]: EdgeFlagPointerEXT (will be remapped) */
+   /* _mesa_function_pool[15468]: EdgeFlagPointerEXT (will be remapped) */
    "iip\0"
    "glEdgeFlagPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[15405]: VertexAttribs2svNV (will be remapped) */
+   /* _mesa_function_pool[15494]: VertexAttribs2svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs2svNV\0"
    "\0"
-   /* _mesa_function_pool[15431]: WeightbvARB (dynamic) */
+   /* _mesa_function_pool[15520]: WeightbvARB (dynamic) */
    "ip\0"
    "glWeightbvARB\0"
    "\0"
-   /* _mesa_function_pool[15449]: VertexAttrib2fvARB (will be remapped) */
+   /* _mesa_function_pool[15538]: VertexAttrib2fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib2fv\0"
    "glVertexAttrib2fvARB\0"
    "\0"
-   /* _mesa_function_pool[15492]: GetBufferParameterivARB (will be remapped) */
+   /* _mesa_function_pool[15581]: GetBufferParameterivARB (will be remapped) */
    "iip\0"
    "glGetBufferParameteriv\0"
    "glGetBufferParameterivARB\0"
    "\0"
-   /* _mesa_function_pool[15546]: Rectdv (offset 87) */
+   /* _mesa_function_pool[15635]: Rectdv (offset 87) */
    "pp\0"
    "glRectdv\0"
    "\0"
-   /* _mesa_function_pool[15559]: ListParameteriSGIX (dynamic) */
+   /* _mesa_function_pool[15648]: ListParameteriSGIX (dynamic) */
    "iii\0"
    "glListParameteriSGIX\0"
    "\0"
-   /* _mesa_function_pool[15585]: ReplacementCodeuiColor4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[15674]: ReplacementCodeuiColor4fNormal3fVertex3fSUN (dynamic) */
    "iffffffffff\0"
    "glReplacementCodeuiColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[15644]: InstrumentsBufferSGIX (dynamic) */
+   /* _mesa_function_pool[15733]: InstrumentsBufferSGIX (dynamic) */
    "ip\0"
    "glInstrumentsBufferSGIX\0"
    "\0"
-   /* _mesa_function_pool[15672]: VertexAttrib4NivARB (will be remapped) */
+   /* _mesa_function_pool[15761]: VertexAttrib4NivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Niv\0"
    "glVertexAttrib4NivARB\0"
    "\0"
-   /* _mesa_function_pool[15717]: GetAttachedShaders (will be remapped) */
+   /* _mesa_function_pool[15806]: GetAttachedShaders (will be remapped) */
    "iipp\0"
    "glGetAttachedShaders\0"
    "\0"
-   /* _mesa_function_pool[15744]: GenVertexArraysAPPLE (will be remapped) */
+   /* _mesa_function_pool[15833]: GenVertexArraysAPPLE (will be remapped) */
    "ip\0"
    "glGenVertexArraysAPPLE\0"
    "\0"
-   /* _mesa_function_pool[15771]: Materialiv (offset 172) */
+   /* _mesa_function_pool[15860]: Materialiv (offset 172) */
    "iip\0"
    "glMaterialiv\0"
    "\0"
-   /* _mesa_function_pool[15789]: PushClientAttrib (offset 335) */
+   /* _mesa_function_pool[15878]: PushClientAttrib (offset 335) */
    "i\0"
    "glPushClientAttrib\0"
    "\0"
-   /* _mesa_function_pool[15811]: ProgramEnvParameters4fvEXT (will be remapped) */
+   /* _mesa_function_pool[15900]: ProgramEnvParameters4fvEXT (will be remapped) */
    "iiip\0"
    "glProgramEnvParameters4fvEXT\0"
    "\0"
-   /* _mesa_function_pool[15846]: TexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[15935]: TexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
    "pppp\0"
    "glTexCoord2fColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[15892]: WindowPos2iMESA (will be remapped) */
+   /* _mesa_function_pool[15981]: WindowPos2iMESA (will be remapped) */
    "ii\0"
    "glWindowPos2i\0"
    "glWindowPos2iARB\0"
    "glWindowPos2iMESA\0"
    "\0"
-   /* _mesa_function_pool[15945]: SecondaryColor3fvEXT (will be remapped) */
+   /* _mesa_function_pool[16034]: SecondaryColor3fvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3fv\0"
    "glSecondaryColor3fvEXT\0"
    "\0"
-   /* _mesa_function_pool[15991]: PolygonMode (offset 174) */
+   /* _mesa_function_pool[16080]: PolygonMode (offset 174) */
    "ii\0"
    "glPolygonMode\0"
    "\0"
-   /* _mesa_function_pool[16009]: CompressedTexSubImage1DARB (will be remapped) */
+   /* _mesa_function_pool[16098]: CompressedTexSubImage1DARB (will be remapped) */
    "iiiiiip\0"
    "glCompressedTexSubImage1D\0"
    "glCompressedTexSubImage1DARB\0"
    "\0"
-   /* _mesa_function_pool[16073]: GetVertexAttribivNV (will be remapped) */
+   /* _mesa_function_pool[16162]: GetVertexAttribivNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribivNV\0"
    "\0"
-   /* _mesa_function_pool[16100]: GetProgramStringARB (will be remapped) */
+   /* _mesa_function_pool[16189]: GetProgramStringARB (will be remapped) */
    "iip\0"
    "glGetProgramStringARB\0"
    "\0"
-   /* _mesa_function_pool[16127]: TexBumpParameterfvATI (will be remapped) */
+   /* _mesa_function_pool[16216]: TexBumpParameterfvATI (will be remapped) */
    "ip\0"
    "glTexBumpParameterfvATI\0"
    "\0"
-   /* _mesa_function_pool[16155]: CompileShaderARB (will be remapped) */
+   /* _mesa_function_pool[16244]: CompileShaderARB (will be remapped) */
    "i\0"
    "glCompileShader\0"
    "glCompileShaderARB\0"
    "\0"
-   /* _mesa_function_pool[16193]: DeleteShader (will be remapped) */
+   /* _mesa_function_pool[16282]: DeleteShader (will be remapped) */
    "i\0"
    "glDeleteShader\0"
    "\0"
-   /* _mesa_function_pool[16211]: DisableClientState (offset 309) */
+   /* _mesa_function_pool[16300]: DisableClientState (offset 309) */
    "i\0"
    "glDisableClientState\0"
    "\0"
-   /* _mesa_function_pool[16235]: TexGeni (offset 192) */
+   /* _mesa_function_pool[16324]: TexGeni (offset 192) */
    "iii\0"
    "glTexGeni\0"
    "\0"
-   /* _mesa_function_pool[16250]: TexGenf (offset 190) */
+   /* _mesa_function_pool[16339]: TexGenf (offset 190) */
    "iif\0"
    "glTexGenf\0"
    "\0"
-   /* _mesa_function_pool[16265]: Uniform3fARB (will be remapped) */
+   /* _mesa_function_pool[16354]: Uniform3fARB (will be remapped) */
    "ifff\0"
    "glUniform3f\0"
    "glUniform3fARB\0"
    "\0"
-   /* _mesa_function_pool[16298]: TexGend (offset 188) */
+   /* _mesa_function_pool[16387]: TexGend (offset 188) */
    "iid\0"
    "glTexGend\0"
    "\0"
-   /* _mesa_function_pool[16313]: ListParameterfvSGIX (dynamic) */
+   /* _mesa_function_pool[16402]: ListParameterfvSGIX (dynamic) */
    "iip\0"
    "glListParameterfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[16340]: GetPolygonStipple (offset 274) */
+   /* _mesa_function_pool[16429]: GetPolygonStipple (offset 274) */
    "p\0"
    "glGetPolygonStipple\0"
    "\0"
-   /* _mesa_function_pool[16363]: Tangent3dvEXT (dynamic) */
+   /* _mesa_function_pool[16452]: Tangent3dvEXT (dynamic) */
    "p\0"
    "glTangent3dvEXT\0"
    "\0"
-   /* _mesa_function_pool[16382]: GetVertexAttribfvNV (will be remapped) */
+   /* _mesa_function_pool[16471]: GetVertexAttribfvNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribfvNV\0"
    "\0"
-   /* _mesa_function_pool[16409]: WindowPos3sMESA (will be remapped) */
+   /* _mesa_function_pool[16498]: WindowPos3sMESA (will be remapped) */
    "iii\0"
    "glWindowPos3s\0"
    "glWindowPos3sARB\0"
    "glWindowPos3sMESA\0"
    "\0"
-   /* _mesa_function_pool[16463]: VertexAttrib2svNV (will be remapped) */
+   /* _mesa_function_pool[16552]: VertexAttrib2svNV (will be remapped) */
    "ip\0"
    "glVertexAttrib2svNV\0"
    "\0"
-   /* _mesa_function_pool[16487]: VertexAttribs1fvNV (will be remapped) */
+   /* _mesa_function_pool[16576]: VertexAttribs1fvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs1fvNV\0"
    "\0"
-   /* _mesa_function_pool[16513]: TexCoord2fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[16602]: TexCoord2fVertex3fvSUN (dynamic) */
    "pp\0"
    "glTexCoord2fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[16542]: WindowPos4sMESA (will be remapped) */
+   /* _mesa_function_pool[16631]: WindowPos4sMESA (will be remapped) */
    "iiii\0"
    "glWindowPos4sMESA\0"
    "\0"
-   /* _mesa_function_pool[16566]: VertexAttrib4NuivARB (will be remapped) */
+   /* _mesa_function_pool[16655]: VertexAttrib4NuivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nuiv\0"
    "glVertexAttrib4NuivARB\0"
    "\0"
-   /* _mesa_function_pool[16613]: ClientActiveTextureARB (offset 375) */
+   /* _mesa_function_pool[16702]: ClientActiveTextureARB (offset 375) */
    "i\0"
    "glClientActiveTexture\0"
    "glClientActiveTextureARB\0"
    "\0"
-   /* _mesa_function_pool[16663]: PixelTexGenSGIX (will be remapped) */
+   /* _mesa_function_pool[16752]: PixelTexGenSGIX (will be remapped) */
    "i\0"
    "glPixelTexGenSGIX\0"
    "\0"
-   /* _mesa_function_pool[16684]: ReplacementCodeusvSUN (dynamic) */
+   /* _mesa_function_pool[16773]: ReplacementCodeusvSUN (dynamic) */
    "p\0"
    "glReplacementCodeusvSUN\0"
    "\0"
-   /* _mesa_function_pool[16711]: Uniform4fARB (will be remapped) */
+   /* _mesa_function_pool[16800]: Uniform4fARB (will be remapped) */
    "iffff\0"
    "glUniform4f\0"
    "glUniform4fARB\0"
    "\0"
-   /* _mesa_function_pool[16745]: Color4sv (offset 34) */
+   /* _mesa_function_pool[16834]: Color4sv (offset 34) */
    "p\0"
    "glColor4sv\0"
    "\0"
-   /* _mesa_function_pool[16759]: FlushMappedBufferRange (will be remapped) */
+   /* _mesa_function_pool[16848]: FlushMappedBufferRange (will be remapped) */
    "iii\0"
    "glFlushMappedBufferRange\0"
    "\0"
-   /* _mesa_function_pool[16789]: IsProgramNV (will be remapped) */
+   /* _mesa_function_pool[16878]: IsProgramNV (will be remapped) */
    "i\0"
    "glIsProgramARB\0"
    "glIsProgramNV\0"
    "\0"
-   /* _mesa_function_pool[16821]: FlushMappedBufferRangeAPPLE (will be remapped) */
+   /* _mesa_function_pool[16910]: FlushMappedBufferRangeAPPLE (will be remapped) */
    "iii\0"
    "glFlushMappedBufferRangeAPPLE\0"
    "\0"
-   /* _mesa_function_pool[16856]: PixelZoom (offset 246) */
+   /* _mesa_function_pool[16945]: PixelZoom (offset 246) */
    "ff\0"
    "glPixelZoom\0"
    "\0"
-   /* _mesa_function_pool[16872]: ReplacementCodePointerSUN (dynamic) */
+   /* _mesa_function_pool[16961]: ReplacementCodePointerSUN (dynamic) */
    "iip\0"
    "glReplacementCodePointerSUN\0"
    "\0"
-   /* _mesa_function_pool[16905]: ProgramEnvParameter4dARB (will be remapped) */
+   /* _mesa_function_pool[16994]: ProgramEnvParameter4dARB (will be remapped) */
    "iidddd\0"
    "glProgramEnvParameter4dARB\0"
    "glProgramParameter4dNV\0"
    "\0"
-   /* _mesa_function_pool[16963]: ColorTableParameterfv (offset 340) */
+   /* _mesa_function_pool[17052]: ColorTableParameterfv (offset 340) */
    "iip\0"
    "glColorTableParameterfv\0"
    "glColorTableParameterfvSGI\0"
    "\0"
-   /* _mesa_function_pool[17019]: FragmentLightModelfSGIX (dynamic) */
+   /* _mesa_function_pool[17108]: FragmentLightModelfSGIX (dynamic) */
    "if\0"
    "glFragmentLightModelfSGIX\0"
    "\0"
-   /* _mesa_function_pool[17049]: Binormal3bvEXT (dynamic) */
+   /* _mesa_function_pool[17138]: Binormal3bvEXT (dynamic) */
    "p\0"
    "glBinormal3bvEXT\0"
    "\0"
-   /* _mesa_function_pool[17069]: PixelMapuiv (offset 252) */
+   /* _mesa_function_pool[17158]: PixelMapuiv (offset 252) */
    "iip\0"
    "glPixelMapuiv\0"
    "\0"
-   /* _mesa_function_pool[17088]: Color3dv (offset 12) */
+   /* _mesa_function_pool[17177]: Color3dv (offset 12) */
    "p\0"
    "glColor3dv\0"
    "\0"
-   /* _mesa_function_pool[17102]: IsTexture (offset 330) */
+   /* _mesa_function_pool[17191]: IsTexture (offset 330) */
    "i\0"
    "glIsTexture\0"
    "glIsTextureEXT\0"
    "\0"
-   /* _mesa_function_pool[17132]: VertexWeightfvEXT (dynamic) */
+   /* _mesa_function_pool[17221]: VertexWeightfvEXT (dynamic) */
    "p\0"
    "glVertexWeightfvEXT\0"
    "\0"
-   /* _mesa_function_pool[17155]: VertexAttrib1dARB (will be remapped) */
+   /* _mesa_function_pool[17244]: VertexAttrib1dARB (will be remapped) */
    "id\0"
    "glVertexAttrib1d\0"
    "glVertexAttrib1dARB\0"
    "\0"
-   /* _mesa_function_pool[17196]: ImageTransformParameterivHP (dynamic) */
+   /* _mesa_function_pool[17285]: ImageTransformParameterivHP (dynamic) */
    "iip\0"
    "glImageTransformParameterivHP\0"
    "\0"
-   /* _mesa_function_pool[17231]: TexCoord4i (offset 122) */
+   /* _mesa_function_pool[17320]: TexCoord4i (offset 122) */
    "iiii\0"
    "glTexCoord4i\0"
    "\0"
-   /* _mesa_function_pool[17250]: DeleteQueriesARB (will be remapped) */
+   /* _mesa_function_pool[17339]: DeleteQueriesARB (will be remapped) */
    "ip\0"
    "glDeleteQueries\0"
    "glDeleteQueriesARB\0"
    "\0"
-   /* _mesa_function_pool[17289]: Color4ubVertex2fSUN (dynamic) */
+   /* _mesa_function_pool[17378]: Color4ubVertex2fSUN (dynamic) */
    "iiiiff\0"
    "glColor4ubVertex2fSUN\0"
    "\0"
-   /* _mesa_function_pool[17319]: FragmentColorMaterialSGIX (dynamic) */
+   /* _mesa_function_pool[17408]: FragmentColorMaterialSGIX (dynamic) */
    "ii\0"
    "glFragmentColorMaterialSGIX\0"
    "\0"
-   /* _mesa_function_pool[17351]: CurrentPaletteMatrixARB (dynamic) */
+   /* _mesa_function_pool[17440]: CurrentPaletteMatrixARB (dynamic) */
    "i\0"
    "glCurrentPaletteMatrixARB\0"
    "\0"
-   /* _mesa_function_pool[17380]: GetMapdv (offset 266) */
+   /* _mesa_function_pool[17469]: GetMapdv (offset 266) */
    "iip\0"
    "glGetMapdv\0"
    "\0"
-   /* _mesa_function_pool[17396]: SamplePatternSGIS (will be remapped) */
+   /* _mesa_function_pool[17485]: SamplePatternSGIS (will be remapped) */
    "i\0"
    "glSamplePatternSGIS\0"
    "glSamplePatternEXT\0"
    "\0"
-   /* _mesa_function_pool[17438]: PixelStoref (offset 249) */
+   /* _mesa_function_pool[17527]: PixelStoref (offset 249) */
    "if\0"
    "glPixelStoref\0"
    "\0"
-   /* _mesa_function_pool[17456]: IsQueryARB (will be remapped) */
+   /* _mesa_function_pool[17545]: IsQueryARB (will be remapped) */
    "i\0"
    "glIsQuery\0"
    "glIsQueryARB\0"
    "\0"
-   /* _mesa_function_pool[17482]: ReplacementCodeuiColor4ubVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[17571]: ReplacementCodeuiColor4ubVertex3fSUN (dynamic) */
    "iiiiifff\0"
    "glReplacementCodeuiColor4ubVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[17531]: PixelStorei (offset 250) */
+   /* _mesa_function_pool[17620]: PixelStorei (offset 250) */
    "ii\0"
    "glPixelStorei\0"
    "\0"
-   /* _mesa_function_pool[17549]: VertexAttrib4usvARB (will be remapped) */
+   /* _mesa_function_pool[17638]: VertexAttrib4usvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4usv\0"
    "glVertexAttrib4usvARB\0"
    "\0"
-   /* _mesa_function_pool[17594]: LinkProgramARB (will be remapped) */
+   /* _mesa_function_pool[17683]: LinkProgramARB (will be remapped) */
    "i\0"
    "glLinkProgram\0"
    "glLinkProgramARB\0"
    "\0"
-   /* _mesa_function_pool[17628]: VertexAttrib2fNV (will be remapped) */
+   /* _mesa_function_pool[17717]: VertexAttrib2fNV (will be remapped) */
    "iff\0"
    "glVertexAttrib2fNV\0"
    "\0"
-   /* _mesa_function_pool[17652]: ShaderSourceARB (will be remapped) */
+   /* _mesa_function_pool[17741]: ShaderSourceARB (will be remapped) */
    "iipp\0"
    "glShaderSource\0"
    "glShaderSourceARB\0"
    "\0"
-   /* _mesa_function_pool[17691]: FragmentMaterialiSGIX (dynamic) */
+   /* _mesa_function_pool[17780]: FragmentMaterialiSGIX (dynamic) */
    "iii\0"
    "glFragmentMaterialiSGIX\0"
    "\0"
-   /* _mesa_function_pool[17720]: EvalCoord2dv (offset 233) */
+   /* _mesa_function_pool[17809]: EvalCoord2dv (offset 233) */
    "p\0"
    "glEvalCoord2dv\0"
    "\0"
-   /* _mesa_function_pool[17738]: VertexAttrib3svARB (will be remapped) */
+   /* _mesa_function_pool[17827]: VertexAttrib3svARB (will be remapped) */
    "ip\0"
    "glVertexAttrib3sv\0"
    "glVertexAttrib3svARB\0"
    "\0"
-   /* _mesa_function_pool[17781]: ColorMaterial (offset 151) */
+   /* _mesa_function_pool[17870]: ColorMaterial (offset 151) */
    "ii\0"
    "glColorMaterial\0"
    "\0"
-   /* _mesa_function_pool[17801]: CompressedTexSubImage3DARB (will be remapped) */
+   /* _mesa_function_pool[17890]: CompressedTexSubImage3DARB (will be remapped) */
    "iiiiiiiiiip\0"
    "glCompressedTexSubImage3D\0"
    "glCompressedTexSubImage3DARB\0"
    "\0"
-   /* _mesa_function_pool[17869]: WindowPos2ivMESA (will be remapped) */
+   /* _mesa_function_pool[17958]: WindowPos2ivMESA (will be remapped) */
    "p\0"
    "glWindowPos2iv\0"
    "glWindowPos2ivARB\0"
    "glWindowPos2ivMESA\0"
    "\0"
-   /* _mesa_function_pool[17924]: IsFramebufferEXT (will be remapped) */
+   /* _mesa_function_pool[18013]: IsFramebufferEXT (will be remapped) */
    "i\0"
    "glIsFramebuffer\0"
    "glIsFramebufferEXT\0"
    "\0"
-   /* _mesa_function_pool[17962]: Uniform4ivARB (will be remapped) */
+   /* _mesa_function_pool[18051]: Uniform4ivARB (will be remapped) */
    "iip\0"
    "glUniform4iv\0"
    "glUniform4ivARB\0"
    "\0"
-   /* _mesa_function_pool[17996]: GetVertexAttribdvARB (will be remapped) */
+   /* _mesa_function_pool[18085]: GetVertexAttribdvARB (will be remapped) */
    "iip\0"
    "glGetVertexAttribdv\0"
    "glGetVertexAttribdvARB\0"
    "\0"
-   /* _mesa_function_pool[18044]: TexBumpParameterivATI (will be remapped) */
+   /* _mesa_function_pool[18133]: TexBumpParameterivATI (will be remapped) */
    "ip\0"
    "glTexBumpParameterivATI\0"
    "\0"
-   /* _mesa_function_pool[18072]: GetSeparableFilter (offset 359) */
+   /* _mesa_function_pool[18161]: GetSeparableFilter (offset 359) */
    "iiippp\0"
    "glGetSeparableFilter\0"
    "glGetSeparableFilterEXT\0"
    "\0"
-   /* _mesa_function_pool[18125]: Binormal3dEXT (dynamic) */
+   /* _mesa_function_pool[18214]: Binormal3dEXT (dynamic) */
    "ddd\0"
    "glBinormal3dEXT\0"
    "\0"
-   /* _mesa_function_pool[18146]: SpriteParameteriSGIX (dynamic) */
+   /* _mesa_function_pool[18235]: SpriteParameteriSGIX (dynamic) */
    "ii\0"
    "glSpriteParameteriSGIX\0"
    "\0"
-   /* _mesa_function_pool[18173]: RequestResidentProgramsNV (will be remapped) */
+   /* _mesa_function_pool[18262]: RequestResidentProgramsNV (will be remapped) */
    "ip\0"
    "glRequestResidentProgramsNV\0"
    "\0"
-   /* _mesa_function_pool[18205]: TagSampleBufferSGIX (dynamic) */
+   /* _mesa_function_pool[18294]: TagSampleBufferSGIX (dynamic) */
    "\0"
    "glTagSampleBufferSGIX\0"
    "\0"
-   /* _mesa_function_pool[18229]: ReplacementCodeusSUN (dynamic) */
+   /* _mesa_function_pool[18318]: ReplacementCodeusSUN (dynamic) */
    "i\0"
    "glReplacementCodeusSUN\0"
    "\0"
-   /* _mesa_function_pool[18255]: FeedbackBuffer (offset 194) */
+   /* _mesa_function_pool[18344]: FeedbackBuffer (offset 194) */
    "iip\0"
    "glFeedbackBuffer\0"
    "\0"
-   /* _mesa_function_pool[18277]: RasterPos2iv (offset 67) */
+   /* _mesa_function_pool[18366]: RasterPos2iv (offset 67) */
    "p\0"
    "glRasterPos2iv\0"
    "\0"
-   /* _mesa_function_pool[18295]: TexImage1D (offset 182) */
+   /* _mesa_function_pool[18384]: TexImage1D (offset 182) */
    "iiiiiiip\0"
    "glTexImage1D\0"
    "\0"
-   /* _mesa_function_pool[18318]: ListParameterivSGIX (dynamic) */
+   /* _mesa_function_pool[18407]: ListParameterivSGIX (dynamic) */
    "iip\0"
    "glListParameterivSGIX\0"
    "\0"
-   /* _mesa_function_pool[18345]: MultiDrawElementsEXT (will be remapped) */
+   /* _mesa_function_pool[18434]: MultiDrawElementsEXT (will be remapped) */
    "ipipi\0"
    "glMultiDrawElements\0"
    "glMultiDrawElementsEXT\0"
    "\0"
-   /* _mesa_function_pool[18395]: Color3s (offset 17) */
+   /* _mesa_function_pool[18484]: Color3s (offset 17) */
    "iii\0"
    "glColor3s\0"
    "\0"
-   /* _mesa_function_pool[18410]: Uniform1ivARB (will be remapped) */
+   /* _mesa_function_pool[18499]: Uniform1ivARB (will be remapped) */
    "iip\0"
    "glUniform1iv\0"
    "glUniform1ivARB\0"
    "\0"
-   /* _mesa_function_pool[18444]: WindowPos2sMESA (will be remapped) */
+   /* _mesa_function_pool[18533]: WindowPos2sMESA (will be remapped) */
    "ii\0"
    "glWindowPos2s\0"
    "glWindowPos2sARB\0"
    "glWindowPos2sMESA\0"
    "\0"
-   /* _mesa_function_pool[18497]: WeightusvARB (dynamic) */
+   /* _mesa_function_pool[18586]: WeightusvARB (dynamic) */
    "ip\0"
    "glWeightusvARB\0"
    "\0"
-   /* _mesa_function_pool[18516]: TexCoordPointer (offset 320) */
+   /* _mesa_function_pool[18605]: TexCoordPointer (offset 320) */
    "iiip\0"
    "glTexCoordPointer\0"
    "\0"
-   /* _mesa_function_pool[18540]: FogCoordPointerEXT (will be remapped) */
+   /* _mesa_function_pool[18629]: FogCoordPointerEXT (will be remapped) */
    "iip\0"
    "glFogCoordPointer\0"
    "glFogCoordPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[18584]: IndexMaterialEXT (dynamic) */
+   /* _mesa_function_pool[18673]: IndexMaterialEXT (dynamic) */
    "ii\0"
    "glIndexMaterialEXT\0"
    "\0"
-   /* _mesa_function_pool[18607]: Color3i (offset 15) */
+   /* _mesa_function_pool[18696]: Color3i (offset 15) */
    "iii\0"
    "glColor3i\0"
    "\0"
-   /* _mesa_function_pool[18622]: FrontFace (offset 157) */
+   /* _mesa_function_pool[18711]: FrontFace (offset 157) */
    "i\0"
    "glFrontFace\0"
    "\0"
-   /* _mesa_function_pool[18637]: EvalCoord2d (offset 232) */
+   /* _mesa_function_pool[18726]: EvalCoord2d (offset 232) */
    "dd\0"
    "glEvalCoord2d\0"
    "\0"
-   /* _mesa_function_pool[18655]: SecondaryColor3ubvEXT (will be remapped) */
+   /* _mesa_function_pool[18744]: SecondaryColor3ubvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3ubv\0"
    "glSecondaryColor3ubvEXT\0"
    "\0"
-   /* _mesa_function_pool[18703]: EvalCoord2f (offset 234) */
+   /* _mesa_function_pool[18792]: EvalCoord2f (offset 234) */
    "ff\0"
    "glEvalCoord2f\0"
    "\0"
-   /* _mesa_function_pool[18721]: VertexAttrib4dvARB (will be remapped) */
+   /* _mesa_function_pool[18810]: VertexAttrib4dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4dv\0"
    "glVertexAttrib4dvARB\0"
    "\0"
-   /* _mesa_function_pool[18764]: BindAttribLocationARB (will be remapped) */
+   /* _mesa_function_pool[18853]: BindAttribLocationARB (will be remapped) */
    "iip\0"
    "glBindAttribLocation\0"
    "glBindAttribLocationARB\0"
    "\0"
-   /* _mesa_function_pool[18814]: Color3b (offset 9) */
+   /* _mesa_function_pool[18903]: Color3b (offset 9) */
    "iii\0"
    "glColor3b\0"
    "\0"
-   /* _mesa_function_pool[18829]: MultiTexCoord2dARB (offset 384) */
+   /* _mesa_function_pool[18918]: MultiTexCoord2dARB (offset 384) */
    "idd\0"
    "glMultiTexCoord2d\0"
    "glMultiTexCoord2dARB\0"
    "\0"
-   /* _mesa_function_pool[18873]: ExecuteProgramNV (will be remapped) */
+   /* _mesa_function_pool[18962]: ExecuteProgramNV (will be remapped) */
    "iip\0"
    "glExecuteProgramNV\0"
    "\0"
-   /* _mesa_function_pool[18897]: Color3f (offset 13) */
+   /* _mesa_function_pool[18986]: Color3f (offset 13) */
    "fff\0"
    "glColor3f\0"
    "\0"
-   /* _mesa_function_pool[18912]: LightEnviSGIX (dynamic) */
+   /* _mesa_function_pool[19001]: LightEnviSGIX (dynamic) */
    "ii\0"
    "glLightEnviSGIX\0"
    "\0"
-   /* _mesa_function_pool[18932]: Color3d (offset 11) */
+   /* _mesa_function_pool[19021]: Color3d (offset 11) */
    "ddd\0"
    "glColor3d\0"
    "\0"
-   /* _mesa_function_pool[18947]: Normal3dv (offset 55) */
+   /* _mesa_function_pool[19036]: Normal3dv (offset 55) */
    "p\0"
    "glNormal3dv\0"
    "\0"
-   /* _mesa_function_pool[18962]: Lightf (offset 159) */
+   /* _mesa_function_pool[19051]: Lightf (offset 159) */
    "iif\0"
    "glLightf\0"
    "\0"
-   /* _mesa_function_pool[18976]: ReplacementCodeuiSUN (dynamic) */
+   /* _mesa_function_pool[19065]: ReplacementCodeuiSUN (dynamic) */
    "i\0"
    "glReplacementCodeuiSUN\0"
    "\0"
-   /* _mesa_function_pool[19002]: MatrixMode (offset 293) */
+   /* _mesa_function_pool[19091]: MatrixMode (offset 293) */
    "i\0"
    "glMatrixMode\0"
    "\0"
-   /* _mesa_function_pool[19018]: GetPixelMapusv (offset 273) */
+   /* _mesa_function_pool[19107]: GetPixelMapusv (offset 273) */
    "ip\0"
    "glGetPixelMapusv\0"
    "\0"
-   /* _mesa_function_pool[19039]: Lighti (offset 161) */
+   /* _mesa_function_pool[19128]: Lighti (offset 161) */
    "iii\0"
    "glLighti\0"
    "\0"
-   /* _mesa_function_pool[19053]: VertexAttribPointerNV (will be remapped) */
+   /* _mesa_function_pool[19142]: VertexAttribPointerNV (will be remapped) */
    "iiiip\0"
    "glVertexAttribPointerNV\0"
    "\0"
-   /* _mesa_function_pool[19084]: 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[19169]: PixelTransformParameterfEXT (dynamic) */
+   /* _mesa_function_pool[19287]: PixelTransformParameterfEXT (dynamic) */
    "iif\0"
    "glPixelTransformParameterfEXT\0"
    "\0"
-   /* _mesa_function_pool[19204]: MultiTexCoord4dvARB (offset 401) */
+   /* _mesa_function_pool[19322]: MultiTexCoord4dvARB (offset 401) */
    "ip\0"
    "glMultiTexCoord4dv\0"
    "glMultiTexCoord4dvARB\0"
    "\0"
-   /* _mesa_function_pool[19249]: PixelTransformParameteriEXT (dynamic) */
+   /* _mesa_function_pool[19367]: PixelTransformParameteriEXT (dynamic) */
    "iii\0"
    "glPixelTransformParameteriEXT\0"
    "\0"
-   /* _mesa_function_pool[19284]: GetDoublev (offset 260) */
+   /* _mesa_function_pool[19402]: GetDoublev (offset 260) */
    "ip\0"
    "glGetDoublev\0"
    "\0"
-   /* _mesa_function_pool[19301]: MultMatrixd (offset 295) */
+   /* _mesa_function_pool[19419]: MultMatrixd (offset 295) */
    "p\0"
    "glMultMatrixd\0"
    "\0"
-   /* _mesa_function_pool[19318]: MultMatrixf (offset 294) */
+   /* _mesa_function_pool[19436]: MultMatrixf (offset 294) */
    "p\0"
    "glMultMatrixf\0"
    "\0"
-   /* _mesa_function_pool[19335]: TexCoord2fColor4ubVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[19453]: TexCoord2fColor4ubVertex3fSUN (dynamic) */
    "ffiiiifff\0"
    "glTexCoord2fColor4ubVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[19378]: Uniform1iARB (will be remapped) */
+   /* _mesa_function_pool[19496]: Uniform1iARB (will be remapped) */
    "ii\0"
    "glUniform1i\0"
    "glUniform1iARB\0"
    "\0"
-   /* _mesa_function_pool[19409]: VertexAttribPointerARB (will be remapped) */
+   /* _mesa_function_pool[19527]: VertexAttribPointerARB (will be remapped) */
    "iiiiip\0"
    "glVertexAttribPointer\0"
    "glVertexAttribPointerARB\0"
    "\0"
-   /* _mesa_function_pool[19464]: SharpenTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[19582]: SharpenTexFuncSGIS (dynamic) */
    "iip\0"
    "glSharpenTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[19490]: MultiTexCoord4fvARB (offset 403) */
+   /* _mesa_function_pool[19608]: MultiTexCoord4fvARB (offset 403) */
    "ip\0"
    "glMultiTexCoord4fv\0"
    "glMultiTexCoord4fvARB\0"
    "\0"
-   /* _mesa_function_pool[19535]: UniformMatrix2x3fv (will be remapped) */
+   /* _mesa_function_pool[19653]: UniformMatrix2x3fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix2x3fv\0"
    "\0"
-   /* _mesa_function_pool[19562]: TrackMatrixNV (will be remapped) */
+   /* _mesa_function_pool[19680]: TrackMatrixNV (will be remapped) */
    "iiii\0"
    "glTrackMatrixNV\0"
    "\0"
-   /* _mesa_function_pool[19584]: CombinerParameteriNV (will be remapped) */
+   /* _mesa_function_pool[19702]: CombinerParameteriNV (will be remapped) */
    "ii\0"
    "glCombinerParameteriNV\0"
    "\0"
-   /* _mesa_function_pool[19611]: DeleteAsyncMarkersSGIX (dynamic) */
+   /* _mesa_function_pool[19729]: DeleteAsyncMarkersSGIX (dynamic) */
    "ii\0"
    "glDeleteAsyncMarkersSGIX\0"
    "\0"
-   /* _mesa_function_pool[19640]: IsAsyncMarkerSGIX (dynamic) */
+   /* _mesa_function_pool[19758]: IsAsyncMarkerSGIX (dynamic) */
    "i\0"
    "glIsAsyncMarkerSGIX\0"
    "\0"
-   /* _mesa_function_pool[19663]: FrameZoomSGIX (dynamic) */
+   /* _mesa_function_pool[19781]: FrameZoomSGIX (dynamic) */
    "i\0"
    "glFrameZoomSGIX\0"
    "\0"
-   /* _mesa_function_pool[19682]: Normal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[19800]: Normal3fVertex3fvSUN (dynamic) */
    "pp\0"
    "glNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[19709]: RasterPos4sv (offset 85) */
+   /* _mesa_function_pool[19827]: RasterPos4sv (offset 85) */
    "p\0"
    "glRasterPos4sv\0"
    "\0"
-   /* _mesa_function_pool[19727]: VertexAttrib4NsvARB (will be remapped) */
+   /* _mesa_function_pool[19845]: VertexAttrib4NsvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nsv\0"
    "glVertexAttrib4NsvARB\0"
    "\0"
-   /* _mesa_function_pool[19772]: VertexAttrib3fvARB (will be remapped) */
+   /* _mesa_function_pool[19890]: VertexAttrib3fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib3fv\0"
    "glVertexAttrib3fvARB\0"
    "\0"
-   /* _mesa_function_pool[19815]: ClearColor (offset 206) */
+   /* _mesa_function_pool[19933]: ClearColor (offset 206) */
    "ffff\0"
    "glClearColor\0"
    "\0"
-   /* _mesa_function_pool[19834]: GetSynciv (will be remapped) */
+   /* _mesa_function_pool[19952]: GetSynciv (will be remapped) */
    "iiipp\0"
    "glGetSynciv\0"
    "\0"
-   /* _mesa_function_pool[19853]: DeleteFramebuffersEXT (will be remapped) */
+   /* _mesa_function_pool[19971]: DeleteFramebuffersEXT (will be remapped) */
    "ip\0"
    "glDeleteFramebuffers\0"
    "glDeleteFramebuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[19902]: GlobalAlphaFactorsSUN (dynamic) */
+   /* _mesa_function_pool[20020]: GlobalAlphaFactorsSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactorsSUN\0"
    "\0"
-   /* _mesa_function_pool[19929]: 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[19945]: TexSubImage3D (offset 372) */
+   /* _mesa_function_pool[20089]: TexSubImage3D (offset 372) */
    "iiiiiiiiiip\0"
    "glTexSubImage3D\0"
    "glTexSubImage3DEXT\0"
    "\0"
-   /* _mesa_function_pool[19993]: Tangent3fEXT (dynamic) */
+   /* _mesa_function_pool[20137]: Tangent3fEXT (dynamic) */
    "fff\0"
    "glTangent3fEXT\0"
    "\0"
-   /* _mesa_function_pool[20013]: SecondaryColor3uivEXT (will be remapped) */
+   /* _mesa_function_pool[20157]: SecondaryColor3uivEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3uiv\0"
    "glSecondaryColor3uivEXT\0"
    "\0"
-   /* _mesa_function_pool[20061]: MatrixIndexubvARB (dynamic) */
+   /* _mesa_function_pool[20205]: MatrixIndexubvARB (dynamic) */
    "ip\0"
    "glMatrixIndexubvARB\0"
    "\0"
-   /* _mesa_function_pool[20085]: Color4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[20229]: Color4fNormal3fVertex3fSUN (dynamic) */
    "ffffffffff\0"
    "glColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[20126]: PixelTexGenParameterfSGIS (will be remapped) */
+   /* _mesa_function_pool[20270]: PixelTexGenParameterfSGIS (will be remapped) */
    "if\0"
    "glPixelTexGenParameterfSGIS\0"
    "\0"
-   /* _mesa_function_pool[20158]: CreateShader (will be remapped) */
+   /* _mesa_function_pool[20302]: CreateShader (will be remapped) */
    "i\0"
    "glCreateShader\0"
    "\0"
-   /* _mesa_function_pool[20176]: GetColorTableParameterfv (offset 344) */
+   /* _mesa_function_pool[20320]: GetColorTableParameterfv (offset 344) */
    "iip\0"
    "glGetColorTableParameterfv\0"
    "glGetColorTableParameterfvSGI\0"
    "glGetColorTableParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[20268]: FragmentLightModelfvSGIX (dynamic) */
+   /* _mesa_function_pool[20412]: FragmentLightModelfvSGIX (dynamic) */
    "ip\0"
    "glFragmentLightModelfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[20299]: Bitmap (offset 8) */
+   /* _mesa_function_pool[20443]: Bitmap (offset 8) */
    "iiffffp\0"
    "glBitmap\0"
    "\0"
-   /* _mesa_function_pool[20317]: MultiTexCoord3fARB (offset 394) */
+   /* _mesa_function_pool[20461]: MultiTexCoord3fARB (offset 394) */
    "ifff\0"
    "glMultiTexCoord3f\0"
    "glMultiTexCoord3fARB\0"
    "\0"
-   /* _mesa_function_pool[20362]: GetTexLevelParameterfv (offset 284) */
+   /* _mesa_function_pool[20506]: GetTexLevelParameterfv (offset 284) */
    "iiip\0"
    "glGetTexLevelParameterfv\0"
    "\0"
-   /* _mesa_function_pool[20393]: GetPixelTexGenParameterfvSGIS (will be remapped) */
+   /* _mesa_function_pool[20537]: GetPixelTexGenParameterfvSGIS (will be remapped) */
    "ip\0"
    "glGetPixelTexGenParameterfvSGIS\0"
    "\0"
-   /* _mesa_function_pool[20429]: GenFramebuffersEXT (will be remapped) */
+   /* _mesa_function_pool[20573]: GenFramebuffersEXT (will be remapped) */
    "ip\0"
    "glGenFramebuffers\0"
    "glGenFramebuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[20472]: GetProgramParameterdvNV (will be remapped) */
+   /* _mesa_function_pool[20616]: GetProgramParameterdvNV (will be remapped) */
    "iiip\0"
    "glGetProgramParameterdvNV\0"
    "\0"
-   /* _mesa_function_pool[20504]: Vertex2sv (offset 133) */
+   /* _mesa_function_pool[20648]: Vertex2sv (offset 133) */
    "p\0"
    "glVertex2sv\0"
    "\0"
-   /* _mesa_function_pool[20519]: GetIntegerv (offset 263) */
+   /* _mesa_function_pool[20663]: GetIntegerv (offset 263) */
    "ip\0"
    "glGetIntegerv\0"
    "\0"
-   /* _mesa_function_pool[20537]: IsVertexArrayAPPLE (will be remapped) */
+   /* _mesa_function_pool[20681]: IsVertexArrayAPPLE (will be remapped) */
    "i\0"
    "glIsVertexArray\0"
    "glIsVertexArrayAPPLE\0"
    "\0"
-   /* _mesa_function_pool[20577]: FragmentLightfvSGIX (dynamic) */
+   /* _mesa_function_pool[20721]: FragmentLightfvSGIX (dynamic) */
    "iip\0"
    "glFragmentLightfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[20604]: DetachShader (will be remapped) */
+   /* _mesa_function_pool[20748]: DetachShader (will be remapped) */
    "ii\0"
    "glDetachShader\0"
    "\0"
-   /* _mesa_function_pool[20623]: VertexAttrib4NubARB (will be remapped) */
+   /* _mesa_function_pool[20767]: VertexAttrib4NubARB (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4Nub\0"
    "glVertexAttrib4NubARB\0"
    "\0"
-   /* _mesa_function_pool[20671]: GetProgramEnvParameterfvARB (will be remapped) */
+   /* _mesa_function_pool[20815]: GetProgramEnvParameterfvARB (will be remapped) */
    "iip\0"
    "glGetProgramEnvParameterfvARB\0"
    "\0"
-   /* _mesa_function_pool[20706]: GetTrackMatrixivNV (will be remapped) */
+   /* _mesa_function_pool[20850]: GetTrackMatrixivNV (will be remapped) */
    "iiip\0"
    "glGetTrackMatrixivNV\0"
    "\0"
-   /* _mesa_function_pool[20733]: VertexAttrib3svNV (will be remapped) */
+   /* _mesa_function_pool[20877]: VertexAttrib3svNV (will be remapped) */
    "ip\0"
    "glVertexAttrib3svNV\0"
    "\0"
-   /* _mesa_function_pool[20757]: Uniform4fvARB (will be remapped) */
+   /* _mesa_function_pool[20901]: Uniform4fvARB (will be remapped) */
    "iip\0"
    "glUniform4fv\0"
    "glUniform4fvARB\0"
    "\0"
-   /* _mesa_function_pool[20791]: MultTransposeMatrixfARB (will be remapped) */
+   /* _mesa_function_pool[20935]: MultTransposeMatrixfARB (will be remapped) */
    "p\0"
    "glMultTransposeMatrixf\0"
    "glMultTransposeMatrixfARB\0"
    "\0"
-   /* _mesa_function_pool[20843]: GetTexEnviv (offset 277) */
+   /* _mesa_function_pool[20987]: GetTexEnviv (offset 277) */
    "iip\0"
    "glGetTexEnviv\0"
    "\0"
-   /* _mesa_function_pool[20862]: ColorFragmentOp1ATI (will be remapped) */
+   /* _mesa_function_pool[21006]: ColorFragmentOp1ATI (will be remapped) */
    "iiiiiii\0"
    "glColorFragmentOp1ATI\0"
    "\0"
-   /* _mesa_function_pool[20893]: GetUniformfvARB (will be remapped) */
+   /* _mesa_function_pool[21037]: GetUniformfvARB (will be remapped) */
    "iip\0"
    "glGetUniformfv\0"
    "glGetUniformfvARB\0"
    "\0"
-   /* _mesa_function_pool[20931]: PopClientAttrib (offset 334) */
+   /* _mesa_function_pool[21075]: PopClientAttrib (offset 334) */
    "\0"
    "glPopClientAttrib\0"
    "\0"
-   /* _mesa_function_pool[20951]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[21095]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
    "iffffffffffff\0"
    "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[21022]: DetachObjectARB (will be remapped) */
+   /* _mesa_function_pool[21166]: DetachObjectARB (will be remapped) */
    "ii\0"
    "glDetachObjectARB\0"
    "\0"
-   /* _mesa_function_pool[21044]: VertexBlendARB (dynamic) */
+   /* _mesa_function_pool[21188]: VertexBlendARB (dynamic) */
    "i\0"
    "glVertexBlendARB\0"
    "\0"
-   /* _mesa_function_pool[21064]: WindowPos3iMESA (will be remapped) */
+   /* _mesa_function_pool[21208]: WindowPos3iMESA (will be remapped) */
    "iii\0"
    "glWindowPos3i\0"
    "glWindowPos3iARB\0"
    "glWindowPos3iMESA\0"
    "\0"
-   /* _mesa_function_pool[21118]: SeparableFilter2D (offset 360) */
+   /* _mesa_function_pool[21262]: SeparableFilter2D (offset 360) */
    "iiiiiipp\0"
    "glSeparableFilter2D\0"
    "glSeparableFilter2DEXT\0"
    "\0"
-   /* _mesa_function_pool[21171]: ReplacementCodeuiColor4ubVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[21315]: ReplacementCodeuiColor4ubVertex3fvSUN (dynamic) */
    "ppp\0"
    "glReplacementCodeuiColor4ubVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[21216]: Map1d (offset 220) */
+   /* _mesa_function_pool[21360]: Map1d (offset 220) */
    "iddiip\0"
    "glMap1d\0"
    "\0"
-   /* _mesa_function_pool[21232]: Map1f (offset 221) */
+   /* _mesa_function_pool[21376]: Map1f (offset 221) */
    "iffiip\0"
    "glMap1f\0"
    "\0"
-   /* _mesa_function_pool[21248]: CompressedTexImage2DARB (will be remapped) */
+   /* _mesa_function_pool[21392]: CompressedTexImage2DARB (will be remapped) */
    "iiiiiiip\0"
    "glCompressedTexImage2D\0"
    "glCompressedTexImage2DARB\0"
    "\0"
-   /* _mesa_function_pool[21307]: ArrayElement (offset 306) */
+   /* _mesa_function_pool[21451]: ArrayElement (offset 306) */
    "i\0"
    "glArrayElement\0"
    "glArrayElementEXT\0"
    "\0"
-   /* _mesa_function_pool[21343]: TexImage2D (offset 183) */
+   /* _mesa_function_pool[21487]: TexImage2D (offset 183) */
    "iiiiiiiip\0"
    "glTexImage2D\0"
    "\0"
-   /* _mesa_function_pool[21367]: DepthBoundsEXT (will be remapped) */
+   /* _mesa_function_pool[21511]: DepthBoundsEXT (will be remapped) */
    "dd\0"
    "glDepthBoundsEXT\0"
    "\0"
-   /* _mesa_function_pool[21388]: ProgramParameters4fvNV (will be remapped) */
+   /* _mesa_function_pool[21532]: ProgramParameters4fvNV (will be remapped) */
    "iiip\0"
    "glProgramParameters4fvNV\0"
    "\0"
-   /* _mesa_function_pool[21419]: DeformationMap3fSGIX (dynamic) */
+   /* _mesa_function_pool[21563]: DeformationMap3fSGIX (dynamic) */
    "iffiiffiiffiip\0"
    "glDeformationMap3fSGIX\0"
    "\0"
-   /* _mesa_function_pool[21458]: GetProgramivNV (will be remapped) */
+   /* _mesa_function_pool[21602]: GetProgramivNV (will be remapped) */
    "iip\0"
    "glGetProgramivNV\0"
    "\0"
-   /* _mesa_function_pool[21480]: GetMinmaxParameteriv (offset 366) */
+   /* _mesa_function_pool[21624]: GetMinmaxParameteriv (offset 366) */
    "iip\0"
    "glGetMinmaxParameteriv\0"
    "glGetMinmaxParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[21534]: PixelTransferf (offset 247) */
+   /* _mesa_function_pool[21678]: PixelTransferf (offset 247) */
    "if\0"
    "glPixelTransferf\0"
    "\0"
-   /* _mesa_function_pool[21555]: CopyTexImage1D (offset 323) */
+   /* _mesa_function_pool[21699]: CopyTexImage1D (offset 323) */
    "iiiiiii\0"
    "glCopyTexImage1D\0"
    "glCopyTexImage1DEXT\0"
    "\0"
-   /* _mesa_function_pool[21601]: PushMatrix (offset 298) */
+   /* _mesa_function_pool[21745]: PushMatrix (offset 298) */
    "\0"
    "glPushMatrix\0"
    "\0"
-   /* _mesa_function_pool[21616]: Fogiv (offset 156) */
+   /* _mesa_function_pool[21760]: Fogiv (offset 156) */
    "ip\0"
    "glFogiv\0"
    "\0"
-   /* _mesa_function_pool[21628]: TexCoord1dv (offset 95) */
+   /* _mesa_function_pool[21772]: TexCoord1dv (offset 95) */
    "p\0"
    "glTexCoord1dv\0"
    "\0"
-   /* _mesa_function_pool[21645]: AlphaFragmentOp3ATI (will be remapped) */
+   /* _mesa_function_pool[21789]: AlphaFragmentOp3ATI (will be remapped) */
    "iiiiiiiiiiii\0"
    "glAlphaFragmentOp3ATI\0"
    "\0"
-   /* _mesa_function_pool[21681]: PixelTransferi (offset 248) */
+   /* _mesa_function_pool[21825]: PixelTransferi (offset 248) */
    "ii\0"
    "glPixelTransferi\0"
    "\0"
-   /* _mesa_function_pool[21702]: GetVertexAttribdvNV (will be remapped) */
+   /* _mesa_function_pool[21846]: GetVertexAttribdvNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribdvNV\0"
    "\0"
-   /* _mesa_function_pool[21729]: VertexAttrib3fvNV (will be remapped) */
+   /* _mesa_function_pool[21873]: VertexAttrib3fvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib3fvNV\0"
    "\0"
-   /* _mesa_function_pool[21753]: Rotatef (offset 300) */
+   /* _mesa_function_pool[21897]: Rotatef (offset 300) */
    "ffff\0"
    "glRotatef\0"
    "\0"
-   /* _mesa_function_pool[21769]: GetFinalCombinerInputParameterivNV (will be remapped) */
+   /* _mesa_function_pool[21913]: GetFinalCombinerInputParameterivNV (will be remapped) */
    "iip\0"
    "glGetFinalCombinerInputParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[21811]: Vertex3i (offset 138) */
+   /* _mesa_function_pool[21955]: Vertex3i (offset 138) */
    "iii\0"
    "glVertex3i\0"
    "\0"
-   /* _mesa_function_pool[21827]: Vertex3f (offset 136) */
+   /* _mesa_function_pool[21971]: Vertex3f (offset 136) */
    "fff\0"
    "glVertex3f\0"
    "\0"
-   /* _mesa_function_pool[21843]: Clear (offset 203) */
+   /* _mesa_function_pool[21987]: Clear (offset 203) */
    "i\0"
    "glClear\0"
    "\0"
-   /* _mesa_function_pool[21854]: Vertex3d (offset 134) */
+   /* _mesa_function_pool[21998]: Vertex3d (offset 134) */
    "ddd\0"
    "glVertex3d\0"
    "\0"
-   /* _mesa_function_pool[21870]: GetMapParameterivNV (dynamic) */
+   /* _mesa_function_pool[22014]: GetMapParameterivNV (dynamic) */
    "iip\0"
    "glGetMapParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[21897]: Uniform4iARB (will be remapped) */
+   /* _mesa_function_pool[22041]: Uniform4iARB (will be remapped) */
    "iiiii\0"
    "glUniform4i\0"
    "glUniform4iARB\0"
    "\0"
-   /* _mesa_function_pool[21931]: ReadBuffer (offset 254) */
+   /* _mesa_function_pool[22075]: ReadBuffer (offset 254) */
    "i\0"
    "glReadBuffer\0"
    "\0"
-   /* _mesa_function_pool[21947]: ConvolutionParameteri (offset 352) */
+   /* _mesa_function_pool[22091]: ConvolutionParameteri (offset 352) */
    "iii\0"
    "glConvolutionParameteri\0"
    "glConvolutionParameteriEXT\0"
    "\0"
-   /* _mesa_function_pool[22003]: Ortho (offset 296) */
+   /* _mesa_function_pool[22147]: Ortho (offset 296) */
    "dddddd\0"
    "glOrtho\0"
    "\0"
-   /* _mesa_function_pool[22019]: Binormal3sEXT (dynamic) */
+   /* _mesa_function_pool[22163]: Binormal3sEXT (dynamic) */
    "iii\0"
    "glBinormal3sEXT\0"
    "\0"
-   /* _mesa_function_pool[22040]: ListBase (offset 6) */
+   /* _mesa_function_pool[22184]: ListBase (offset 6) */
    "i\0"
    "glListBase\0"
    "\0"
-   /* _mesa_function_pool[22054]: Vertex3s (offset 140) */
+   /* _mesa_function_pool[22198]: Vertex3s (offset 140) */
    "iii\0"
    "glVertex3s\0"
    "\0"
-   /* _mesa_function_pool[22070]: ConvolutionParameterf (offset 350) */
+   /* _mesa_function_pool[22214]: ConvolutionParameterf (offset 350) */
    "iif\0"
    "glConvolutionParameterf\0"
    "glConvolutionParameterfEXT\0"
    "\0"
-   /* _mesa_function_pool[22126]: GetColorTableParameteriv (offset 345) */
+   /* _mesa_function_pool[22270]: GetColorTableParameteriv (offset 345) */
    "iip\0"
    "glGetColorTableParameteriv\0"
    "glGetColorTableParameterivSGI\0"
    "glGetColorTableParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[22218]: ProgramEnvParameter4dvARB (will be remapped) */
+   /* _mesa_function_pool[22362]: ProgramEnvParameter4dvARB (will be remapped) */
    "iip\0"
    "glProgramEnvParameter4dvARB\0"
    "glProgramParameter4dvNV\0"
    "\0"
-   /* _mesa_function_pool[22275]: ShadeModel (offset 177) */
+   /* _mesa_function_pool[22419]: ShadeModel (offset 177) */
    "i\0"
    "glShadeModel\0"
    "\0"
-   /* _mesa_function_pool[22291]: VertexAttribs2fvNV (will be remapped) */
+   /* _mesa_function_pool[22435]: VertexAttribs2fvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs2fvNV\0"
    "\0"
-   /* _mesa_function_pool[22317]: Rectiv (offset 91) */
+   /* _mesa_function_pool[22461]: Rectiv (offset 91) */
    "pp\0"
    "glRectiv\0"
    "\0"
-   /* _mesa_function_pool[22330]: UseProgramObjectARB (will be remapped) */
+   /* _mesa_function_pool[22474]: UseProgramObjectARB (will be remapped) */
    "i\0"
    "glUseProgram\0"
    "glUseProgramObjectARB\0"
    "\0"
-   /* _mesa_function_pool[22368]: GetMapParameterfvNV (dynamic) */
+   /* _mesa_function_pool[22512]: GetMapParameterfvNV (dynamic) */
    "iip\0"
    "glGetMapParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[22395]: 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[22418]: DeleteProgram (will be remapped) */
+   /* _mesa_function_pool[22589]: DeleteProgram (will be remapped) */
    "i\0"
    "glDeleteProgram\0"
    "\0"
-   /* _mesa_function_pool[22437]: Tangent3ivEXT (dynamic) */
+   /* _mesa_function_pool[22608]: Tangent3ivEXT (dynamic) */
    "p\0"
    "glTangent3ivEXT\0"
    "\0"
-   /* _mesa_function_pool[22456]: Tangent3dEXT (dynamic) */
+   /* _mesa_function_pool[22627]: Tangent3dEXT (dynamic) */
    "ddd\0"
    "glTangent3dEXT\0"
    "\0"
-   /* _mesa_function_pool[22476]: SecondaryColor3dvEXT (will be remapped) */
+   /* _mesa_function_pool[22647]: SecondaryColor3dvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3dv\0"
    "glSecondaryColor3dvEXT\0"
    "\0"
-   /* _mesa_function_pool[22522]: Vertex2fv (offset 129) */
+   /* _mesa_function_pool[22693]: Vertex2fv (offset 129) */
    "p\0"
    "glVertex2fv\0"
    "\0"
-   /* _mesa_function_pool[22537]: MultiDrawArraysEXT (will be remapped) */
+   /* _mesa_function_pool[22708]: MultiDrawArraysEXT (will be remapped) */
    "ippi\0"
    "glMultiDrawArrays\0"
    "glMultiDrawArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[22582]: BindRenderbufferEXT (will be remapped) */
+   /* _mesa_function_pool[22753]: BindRenderbufferEXT (will be remapped) */
    "ii\0"
    "glBindRenderbuffer\0"
    "glBindRenderbufferEXT\0"
    "\0"
-   /* _mesa_function_pool[22627]: MultiTexCoord4dARB (offset 400) */
+   /* _mesa_function_pool[22798]: MultiTexCoord4dARB (offset 400) */
    "idddd\0"
    "glMultiTexCoord4d\0"
    "glMultiTexCoord4dARB\0"
    "\0"
-   /* _mesa_function_pool[22673]: Vertex3sv (offset 141) */
+   /* _mesa_function_pool[22844]: Vertex3sv (offset 141) */
    "p\0"
    "glVertex3sv\0"
    "\0"
-   /* _mesa_function_pool[22688]: SecondaryColor3usEXT (will be remapped) */
+   /* _mesa_function_pool[22859]: SecondaryColor3usEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3us\0"
    "glSecondaryColor3usEXT\0"
    "\0"
-   /* _mesa_function_pool[22736]: ProgramLocalParameter4fvARB (will be remapped) */
+   /* _mesa_function_pool[22907]: ProgramLocalParameter4fvARB (will be remapped) */
    "iip\0"
    "glProgramLocalParameter4fvARB\0"
    "\0"
-   /* _mesa_function_pool[22771]: DeleteProgramsNV (will be remapped) */
+   /* _mesa_function_pool[22942]: DeleteProgramsNV (will be remapped) */
    "ip\0"
    "glDeleteProgramsARB\0"
    "glDeleteProgramsNV\0"
    "\0"
-   /* _mesa_function_pool[22814]: EvalMesh1 (offset 236) */
+   /* _mesa_function_pool[22985]: EvalMesh1 (offset 236) */
    "iii\0"
    "glEvalMesh1\0"
    "\0"
-   /* _mesa_function_pool[22831]: MultiTexCoord1sARB (offset 382) */
+   /* _mesa_function_pool[23002]: MultiTexCoord1sARB (offset 382) */
    "ii\0"
    "glMultiTexCoord1s\0"
    "glMultiTexCoord1sARB\0"
    "\0"
-   /* _mesa_function_pool[22874]: ReplacementCodeuiColor3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[23045]: ReplacementCodeuiColor3fVertex3fSUN (dynamic) */
    "iffffff\0"
    "glReplacementCodeuiColor3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[22921]: GetVertexAttribPointervNV (will be remapped) */
+   /* _mesa_function_pool[23092]: GetVertexAttribPointervNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribPointerv\0"
    "glGetVertexAttribPointervARB\0"
    "glGetVertexAttribPointervNV\0"
    "\0"
-   /* _mesa_function_pool[23009]: 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[23054]: Uniform2iARB (will be remapped) */
+   /* _mesa_function_pool[23249]: Uniform2iARB (will be remapped) */
    "iii\0"
    "glUniform2i\0"
    "glUniform2iARB\0"
    "\0"
-   /* _mesa_function_pool[23086]: Vertex2iv (offset 131) */
+   /* _mesa_function_pool[23281]: Vertex2iv (offset 131) */
    "p\0"
    "glVertex2iv\0"
    "\0"
-   /* _mesa_function_pool[23101]: GetProgramStringNV (will be remapped) */
+   /* _mesa_function_pool[23296]: GetProgramStringNV (will be remapped) */
    "iip\0"
    "glGetProgramStringNV\0"
    "\0"
-   /* _mesa_function_pool[23127]: ColorPointerEXT (will be remapped) */
+   /* _mesa_function_pool[23322]: ColorPointerEXT (will be remapped) */
    "iiiip\0"
    "glColorPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[23152]: LineWidth (offset 168) */
+   /* _mesa_function_pool[23347]: LineWidth (offset 168) */
    "f\0"
    "glLineWidth\0"
    "\0"
-   /* _mesa_function_pool[23167]: MapBufferARB (will be remapped) */
+   /* _mesa_function_pool[23362]: MapBufferARB (will be remapped) */
    "ii\0"
    "glMapBuffer\0"
    "glMapBufferARB\0"
    "\0"
-   /* _mesa_function_pool[23198]: MultiDrawElementsBaseVertex (will be remapped) */
+   /* _mesa_function_pool[23393]: MultiDrawElementsBaseVertex (will be remapped) */
    "ipipip\0"
    "glMultiDrawElementsBaseVertex\0"
    "\0"
-   /* _mesa_function_pool[23236]: Binormal3svEXT (dynamic) */
+   /* _mesa_function_pool[23431]: Binormal3svEXT (dynamic) */
    "p\0"
    "glBinormal3svEXT\0"
    "\0"
-   /* _mesa_function_pool[23256]: ApplyTextureEXT (dynamic) */
+   /* _mesa_function_pool[23451]: ApplyTextureEXT (dynamic) */
    "i\0"
    "glApplyTextureEXT\0"
    "\0"
-   /* _mesa_function_pool[23277]: TexGendv (offset 189) */
+   /* _mesa_function_pool[23472]: TexGendv (offset 189) */
    "iip\0"
    "glTexGendv\0"
    "\0"
-   /* _mesa_function_pool[23293]: 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[23318]: TextureLightEXT (dynamic) */
+   /* _mesa_function_pool[23536]: TextureLightEXT (dynamic) */
    "i\0"
    "glTextureLightEXT\0"
    "\0"
-   /* _mesa_function_pool[23339]: ResetMinmax (offset 370) */
+   /* _mesa_function_pool[23557]: ResetMinmax (offset 370) */
    "i\0"
    "glResetMinmax\0"
    "glResetMinmaxEXT\0"
    "\0"
-   /* _mesa_function_pool[23373]: SpriteParameterfSGIX (dynamic) */
+   /* _mesa_function_pool[23591]: SpriteParameterfSGIX (dynamic) */
    "if\0"
    "glSpriteParameterfSGIX\0"
    "\0"
-   /* _mesa_function_pool[23400]: EnableClientState (offset 313) */
+   /* _mesa_function_pool[23618]: EnableClientState (offset 313) */
    "i\0"
    "glEnableClientState\0"
    "\0"
-   /* _mesa_function_pool[23423]: VertexAttrib4sNV (will be remapped) */
+   /* _mesa_function_pool[23641]: VertexAttrib4sNV (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4sNV\0"
    "\0"
-   /* _mesa_function_pool[23449]: GetConvolutionParameterfv (offset 357) */
+   /* _mesa_function_pool[23667]: GetConvolutionParameterfv (offset 357) */
    "iip\0"
    "glGetConvolutionParameterfv\0"
    "glGetConvolutionParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[23513]: VertexAttribs4dvNV (will be remapped) */
+   /* _mesa_function_pool[23731]: VertexAttribs4dvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4dvNV\0"
    "\0"
-   /* _mesa_function_pool[23539]: MultiModeDrawArraysIBM (will be remapped) */
+   /* _mesa_function_pool[23757]: MultiModeDrawArraysIBM (will be remapped) */
    "pppii\0"
    "glMultiModeDrawArraysIBM\0"
    "\0"
-   /* _mesa_function_pool[23571]: VertexAttrib4dARB (will be remapped) */
+   /* _mesa_function_pool[23789]: VertexAttrib4dARB (will be remapped) */
    "idddd\0"
    "glVertexAttrib4d\0"
    "glVertexAttrib4dARB\0"
    "\0"
-   /* _mesa_function_pool[23615]: GetTexBumpParameterfvATI (will be remapped) */
+   /* _mesa_function_pool[23833]: GetTexBumpParameterfvATI (will be remapped) */
    "ip\0"
    "glGetTexBumpParameterfvATI\0"
    "\0"
-   /* _mesa_function_pool[23646]: ProgramNamedParameter4dNV (will be remapped) */
+   /* _mesa_function_pool[23864]: ProgramNamedParameter4dNV (will be remapped) */
    "iipdddd\0"
    "glProgramNamedParameter4dNV\0"
    "\0"
-   /* _mesa_function_pool[23683]: GetMaterialfv (offset 269) */
+   /* _mesa_function_pool[23901]: GetMaterialfv (offset 269) */
    "iip\0"
    "glGetMaterialfv\0"
    "\0"
-   /* _mesa_function_pool[23704]: VertexWeightfEXT (dynamic) */
+   /* _mesa_function_pool[23922]: VertexWeightfEXT (dynamic) */
    "f\0"
    "glVertexWeightfEXT\0"
    "\0"
-   /* _mesa_function_pool[23726]: Binormal3fEXT (dynamic) */
+   /* _mesa_function_pool[23944]: Binormal3fEXT (dynamic) */
    "fff\0"
    "glBinormal3fEXT\0"
    "\0"
-   /* _mesa_function_pool[23747]: CallList (offset 2) */
+   /* _mesa_function_pool[23965]: CallList (offset 2) */
    "i\0"
    "glCallList\0"
    "\0"
-   /* _mesa_function_pool[23761]: Materialfv (offset 170) */
+   /* _mesa_function_pool[23979]: Materialfv (offset 170) */
    "iip\0"
    "glMaterialfv\0"
    "\0"
-   /* _mesa_function_pool[23779]: TexCoord3fv (offset 113) */
+   /* _mesa_function_pool[23997]: TexCoord3fv (offset 113) */
    "p\0"
    "glTexCoord3fv\0"
    "\0"
-   /* _mesa_function_pool[23796]: FogCoordfvEXT (will be remapped) */
+   /* _mesa_function_pool[24014]: FogCoordfvEXT (will be remapped) */
    "p\0"
    "glFogCoordfv\0"
    "glFogCoordfvEXT\0"
    "\0"
-   /* _mesa_function_pool[23828]: MultiTexCoord1ivARB (offset 381) */
+   /* _mesa_function_pool[24046]: MultiTexCoord1ivARB (offset 381) */
    "ip\0"
    "glMultiTexCoord1iv\0"
    "glMultiTexCoord1ivARB\0"
    "\0"
-   /* _mesa_function_pool[23873]: SecondaryColor3ubEXT (will be remapped) */
+   /* _mesa_function_pool[24091]: SecondaryColor3ubEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3ub\0"
    "glSecondaryColor3ubEXT\0"
    "\0"
-   /* _mesa_function_pool[23921]: MultiTexCoord2ivARB (offset 389) */
+   /* _mesa_function_pool[24139]: MultiTexCoord2ivARB (offset 389) */
    "ip\0"
    "glMultiTexCoord2iv\0"
    "glMultiTexCoord2ivARB\0"
    "\0"
-   /* _mesa_function_pool[23966]: FogFuncSGIS (dynamic) */
+   /* _mesa_function_pool[24184]: FogFuncSGIS (dynamic) */
    "ip\0"
    "glFogFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[23984]: CopyTexSubImage2D (offset 326) */
+   /* _mesa_function_pool[24202]: CopyTexSubImage2D (offset 326) */
    "iiiiiiii\0"
    "glCopyTexSubImage2D\0"
    "glCopyTexSubImage2DEXT\0"
    "\0"
-   /* _mesa_function_pool[24037]: GetObjectParameterivARB (will be remapped) */
+   /* _mesa_function_pool[24255]: GetObjectParameterivARB (will be remapped) */
    "iip\0"
    "glGetObjectParameterivARB\0"
    "\0"
-   /* _mesa_function_pool[24068]: Color3iv (offset 16) */
+   /* _mesa_function_pool[24286]: Color3iv (offset 16) */
    "p\0"
    "glColor3iv\0"
    "\0"
-   /* _mesa_function_pool[24082]: TexCoord4fVertex4fSUN (dynamic) */
+   /* _mesa_function_pool[24300]: TexCoord4fVertex4fSUN (dynamic) */
    "ffffffff\0"
    "glTexCoord4fVertex4fSUN\0"
    "\0"
-   /* _mesa_function_pool[24116]: DrawElements (offset 311) */
+   /* _mesa_function_pool[24334]: DrawElements (offset 311) */
    "iiip\0"
    "glDrawElements\0"
    "\0"
-   /* _mesa_function_pool[24137]: BindVertexArrayAPPLE (will be remapped) */
+   /* _mesa_function_pool[24355]: BindVertexArrayAPPLE (will be remapped) */
    "i\0"
    "glBindVertexArrayAPPLE\0"
    "\0"
-   /* _mesa_function_pool[24163]: GetProgramLocalParameterdvARB (will be remapped) */
+   /* _mesa_function_pool[24381]: GetProgramLocalParameterdvARB (will be remapped) */
    "iip\0"
    "glGetProgramLocalParameterdvARB\0"
    "\0"
-   /* _mesa_function_pool[24200]: GetHistogramParameteriv (offset 363) */
+   /* _mesa_function_pool[24418]: GetHistogramParameteriv (offset 363) */
    "iip\0"
    "glGetHistogramParameteriv\0"
    "glGetHistogramParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[24260]: MultiTexCoord1iARB (offset 380) */
+   /* _mesa_function_pool[24478]: MultiTexCoord1iARB (offset 380) */
    "ii\0"
    "glMultiTexCoord1i\0"
    "glMultiTexCoord1iARB\0"
    "\0"
-   /* _mesa_function_pool[24303]: GetConvolutionFilter (offset 356) */
+   /* _mesa_function_pool[24521]: GetConvolutionFilter (offset 356) */
    "iiip\0"
    "glGetConvolutionFilter\0"
    "glGetConvolutionFilterEXT\0"
    "\0"
-   /* _mesa_function_pool[24358]: GetProgramivARB (will be remapped) */
+   /* _mesa_function_pool[24576]: GetProgramivARB (will be remapped) */
    "iip\0"
    "glGetProgramivARB\0"
    "\0"
-   /* _mesa_function_pool[24381]: BlendFuncSeparateEXT (will be remapped) */
+   /* _mesa_function_pool[24599]: BlendFuncSeparateEXT (will be remapped) */
    "iiii\0"
    "glBlendFuncSeparate\0"
    "glBlendFuncSeparateEXT\0"
    "glBlendFuncSeparateINGR\0"
    "\0"
-   /* _mesa_function_pool[24454]: MapBufferRange (will be remapped) */
+   /* _mesa_function_pool[24672]: MapBufferRange (will be remapped) */
    "iiii\0"
    "glMapBufferRange\0"
    "\0"
-   /* _mesa_function_pool[24477]: ProgramParameters4dvNV (will be remapped) */
+   /* _mesa_function_pool[24695]: ProgramParameters4dvNV (will be remapped) */
    "iiip\0"
    "glProgramParameters4dvNV\0"
    "\0"
-   /* _mesa_function_pool[24508]: TexCoord2fColor3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[24726]: TexCoord2fColor3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glTexCoord2fColor3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[24545]: EvalPoint2 (offset 239) */
+   /* _mesa_function_pool[24763]: EvalPoint2 (offset 239) */
    "ii\0"
    "glEvalPoint2\0"
    "\0"
-   /* _mesa_function_pool[24562]: EvalPoint1 (offset 237) */
+   /* _mesa_function_pool[24780]: EvalPoint1 (offset 237) */
    "i\0"
    "glEvalPoint1\0"
    "\0"
-   /* _mesa_function_pool[24578]: Binormal3dvEXT (dynamic) */
+   /* _mesa_function_pool[24796]: Binormal3dvEXT (dynamic) */
    "p\0"
    "glBinormal3dvEXT\0"
    "\0"
-   /* _mesa_function_pool[24598]: PopMatrix (offset 297) */
+   /* _mesa_function_pool[24816]: PopMatrix (offset 297) */
    "\0"
    "glPopMatrix\0"
    "\0"
-   /* _mesa_function_pool[24612]: FinishFenceNV (will be remapped) */
+   /* _mesa_function_pool[24830]: FinishFenceNV (will be remapped) */
    "i\0"
    "glFinishFenceNV\0"
    "\0"
-   /* _mesa_function_pool[24631]: GetFogFuncSGIS (dynamic) */
+   /* _mesa_function_pool[24849]: GetFogFuncSGIS (dynamic) */
    "p\0"
    "glGetFogFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[24651]: GetUniformLocationARB (will be remapped) */
+   /* _mesa_function_pool[24869]: GetUniformLocationARB (will be remapped) */
    "ip\0"
    "glGetUniformLocation\0"
    "glGetUniformLocationARB\0"
    "\0"
-   /* _mesa_function_pool[24700]: SecondaryColor3fEXT (will be remapped) */
+   /* _mesa_function_pool[24918]: SecondaryColor3fEXT (will be remapped) */
    "fff\0"
    "glSecondaryColor3f\0"
    "glSecondaryColor3fEXT\0"
    "\0"
-   /* _mesa_function_pool[24746]: GetTexGeniv (offset 280) */
+   /* _mesa_function_pool[24964]: GetTexGeniv (offset 280) */
    "iip\0"
    "glGetTexGeniv\0"
    "\0"
-   /* _mesa_function_pool[24765]: CombinerInputNV (will be remapped) */
+   /* _mesa_function_pool[24983]: CombinerInputNV (will be remapped) */
    "iiiiii\0"
    "glCombinerInputNV\0"
    "\0"
-   /* _mesa_function_pool[24791]: VertexAttrib3sARB (will be remapped) */
+   /* _mesa_function_pool[25009]: VertexAttrib3sARB (will be remapped) */
    "iiii\0"
    "glVertexAttrib3s\0"
    "glVertexAttrib3sARB\0"
    "\0"
-   /* _mesa_function_pool[24834]: ReplacementCodeuiNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[25052]: ReplacementCodeuiNormal3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glReplacementCodeuiNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[24879]: Map2d (offset 222) */
+   /* _mesa_function_pool[25097]: Map2d (offset 222) */
    "iddiiddiip\0"
    "glMap2d\0"
    "\0"
-   /* _mesa_function_pool[24899]: Map2f (offset 223) */
+   /* _mesa_function_pool[25117]: Map2f (offset 223) */
    "iffiiffiip\0"
    "glMap2f\0"
    "\0"
-   /* _mesa_function_pool[24919]: ProgramStringARB (will be remapped) */
+   /* _mesa_function_pool[25137]: ProgramStringARB (will be remapped) */
    "iiip\0"
    "glProgramStringARB\0"
    "\0"
-   /* _mesa_function_pool[24944]: Vertex4s (offset 148) */
+   /* _mesa_function_pool[25162]: Vertex4s (offset 148) */
    "iiii\0"
    "glVertex4s\0"
    "\0"
-   /* _mesa_function_pool[24961]: TexCoord4fVertex4fvSUN (dynamic) */
+   /* _mesa_function_pool[25179]: TexCoord4fVertex4fvSUN (dynamic) */
    "pp\0"
    "glTexCoord4fVertex4fvSUN\0"
    "\0"
-   /* _mesa_function_pool[24990]: VertexAttrib3sNV (will be remapped) */
+   /* _mesa_function_pool[25208]: VertexAttrib3sNV (will be remapped) */
    "iiii\0"
    "glVertexAttrib3sNV\0"
    "\0"
-   /* _mesa_function_pool[25015]: VertexAttrib1fNV (will be remapped) */
+   /* _mesa_function_pool[25233]: VertexAttrib1fNV (will be remapped) */
    "if\0"
    "glVertexAttrib1fNV\0"
    "\0"
-   /* _mesa_function_pool[25038]: Vertex4f (offset 144) */
+   /* _mesa_function_pool[25256]: Vertex4f (offset 144) */
    "ffff\0"
    "glVertex4f\0"
    "\0"
-   /* _mesa_function_pool[25055]: EvalCoord1d (offset 228) */
+   /* _mesa_function_pool[25273]: EvalCoord1d (offset 228) */
    "d\0"
    "glEvalCoord1d\0"
    "\0"
-   /* _mesa_function_pool[25072]: Vertex4d (offset 142) */
+   /* _mesa_function_pool[25290]: Vertex4d (offset 142) */
    "dddd\0"
    "glVertex4d\0"
    "\0"
-   /* _mesa_function_pool[25089]: RasterPos4dv (offset 79) */
+   /* _mesa_function_pool[25307]: RasterPos4dv (offset 79) */
    "p\0"
    "glRasterPos4dv\0"
    "\0"
-   /* _mesa_function_pool[25107]: FragmentLightfSGIX (dynamic) */
+   /* _mesa_function_pool[25325]: FragmentLightfSGIX (dynamic) */
    "iif\0"
    "glFragmentLightfSGIX\0"
    "\0"
-   /* _mesa_function_pool[25133]: GetCompressedTexImageARB (will be remapped) */
+   /* _mesa_function_pool[25351]: GetCompressedTexImageARB (will be remapped) */
    "iip\0"
    "glGetCompressedTexImage\0"
    "glGetCompressedTexImageARB\0"
    "\0"
-   /* _mesa_function_pool[25189]: GetTexGenfv (offset 279) */
+   /* _mesa_function_pool[25407]: GetTexGenfv (offset 279) */
    "iip\0"
    "glGetTexGenfv\0"
    "\0"
-   /* _mesa_function_pool[25208]: Vertex4i (offset 146) */
+   /* _mesa_function_pool[25426]: Vertex4i (offset 146) */
    "iiii\0"
    "glVertex4i\0"
    "\0"
-   /* _mesa_function_pool[25225]: VertexWeightPointerEXT (dynamic) */
+   /* _mesa_function_pool[25443]: VertexWeightPointerEXT (dynamic) */
    "iiip\0"
    "glVertexWeightPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[25256]: GetHistogram (offset 361) */
+   /* _mesa_function_pool[25474]: GetHistogram (offset 361) */
    "iiiip\0"
    "glGetHistogram\0"
    "glGetHistogramEXT\0"
    "\0"
-   /* _mesa_function_pool[25296]: ActiveStencilFaceEXT (will be remapped) */
+   /* _mesa_function_pool[25514]: ActiveStencilFaceEXT (will be remapped) */
    "i\0"
    "glActiveStencilFaceEXT\0"
    "\0"
-   /* _mesa_function_pool[25322]: StencilFuncSeparateATI (will be remapped) */
+   /* _mesa_function_pool[25540]: StencilFuncSeparateATI (will be remapped) */
    "iiii\0"
    "glStencilFuncSeparateATI\0"
    "\0"
-   /* _mesa_function_pool[25353]: Materialf (offset 169) */
+   /* _mesa_function_pool[25571]: Materialf (offset 169) */
    "iif\0"
    "glMaterialf\0"
    "\0"
-   /* _mesa_function_pool[25370]: GetShaderSourceARB (will be remapped) */
+   /* _mesa_function_pool[25588]: GetShaderSourceARB (will be remapped) */
    "iipp\0"
    "glGetShaderSource\0"
    "glGetShaderSourceARB\0"
    "\0"
-   /* _mesa_function_pool[25415]: IglooInterfaceSGIX (dynamic) */
+   /* _mesa_function_pool[25633]: IglooInterfaceSGIX (dynamic) */
    "ip\0"
    "glIglooInterfaceSGIX\0"
    "\0"
-   /* _mesa_function_pool[25440]: Materiali (offset 171) */
+   /* _mesa_function_pool[25658]: Materiali (offset 171) */
    "iii\0"
    "glMateriali\0"
    "\0"
-   /* _mesa_function_pool[25457]: VertexAttrib4dNV (will be remapped) */
+   /* _mesa_function_pool[25675]: VertexAttrib4dNV (will be remapped) */
    "idddd\0"
    "glVertexAttrib4dNV\0"
    "\0"
-   /* _mesa_function_pool[25483]: MultiModeDrawElementsIBM (will be remapped) */
+   /* _mesa_function_pool[25701]: MultiModeDrawElementsIBM (will be remapped) */
    "ppipii\0"
    "glMultiModeDrawElementsIBM\0"
    "\0"
-   /* _mesa_function_pool[25518]: Indexsv (offset 51) */
+   /* _mesa_function_pool[25736]: Indexsv (offset 51) */
    "p\0"
    "glIndexsv\0"
    "\0"
-   /* _mesa_function_pool[25531]: MultiTexCoord4svARB (offset 407) */
+   /* _mesa_function_pool[25749]: MultiTexCoord4svARB (offset 407) */
    "ip\0"
    "glMultiTexCoord4sv\0"
    "glMultiTexCoord4svARB\0"
    "\0"
-   /* _mesa_function_pool[25576]: LightModelfv (offset 164) */
+   /* _mesa_function_pool[25794]: LightModelfv (offset 164) */
    "ip\0"
    "glLightModelfv\0"
    "\0"
-   /* _mesa_function_pool[25595]: TexCoord2dv (offset 103) */
+   /* _mesa_function_pool[25813]: TexCoord2dv (offset 103) */
    "p\0"
    "glTexCoord2dv\0"
    "\0"
-   /* _mesa_function_pool[25612]: GenQueriesARB (will be remapped) */
+   /* _mesa_function_pool[25830]: GenQueriesARB (will be remapped) */
    "ip\0"
    "glGenQueries\0"
    "glGenQueriesARB\0"
    "\0"
-   /* _mesa_function_pool[25645]: EvalCoord1dv (offset 229) */
+   /* _mesa_function_pool[25863]: EvalCoord1dv (offset 229) */
    "p\0"
    "glEvalCoord1dv\0"
    "\0"
-   /* _mesa_function_pool[25663]: ReplacementCodeuiVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[25881]: ReplacementCodeuiVertex3fSUN (dynamic) */
    "ifff\0"
    "glReplacementCodeuiVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[25700]: Translated (offset 303) */
+   /* _mesa_function_pool[25918]: Translated (offset 303) */
    "ddd\0"
    "glTranslated\0"
    "\0"
-   /* _mesa_function_pool[25718]: Translatef (offset 304) */
+   /* _mesa_function_pool[25936]: Translatef (offset 304) */
    "fff\0"
    "glTranslatef\0"
    "\0"
-   /* _mesa_function_pool[25736]: StencilMask (offset 209) */
+   /* _mesa_function_pool[25954]: StencilMask (offset 209) */
    "i\0"
    "glStencilMask\0"
    "\0"
-   /* _mesa_function_pool[25753]: Tangent3iEXT (dynamic) */
+   /* _mesa_function_pool[25971]: Tangent3iEXT (dynamic) */
    "iii\0"
    "glTangent3iEXT\0"
    "\0"
-   /* _mesa_function_pool[25773]: GetLightiv (offset 265) */
+   /* _mesa_function_pool[25991]: GetLightiv (offset 265) */
    "iip\0"
    "glGetLightiv\0"
    "\0"
-   /* _mesa_function_pool[25791]: DrawMeshArraysSUN (dynamic) */
+   /* _mesa_function_pool[26009]: DrawMeshArraysSUN (dynamic) */
    "iiii\0"
    "glDrawMeshArraysSUN\0"
    "\0"
-   /* _mesa_function_pool[25817]: IsList (offset 287) */
+   /* _mesa_function_pool[26035]: IsList (offset 287) */
    "i\0"
    "glIsList\0"
    "\0"
-   /* _mesa_function_pool[25829]: IsSync (will be remapped) */
+   /* _mesa_function_pool[26047]: IsSync (will be remapped) */
    "i\0"
    "glIsSync\0"
    "\0"
-   /* _mesa_function_pool[25841]: RenderMode (offset 196) */
+   /* _mesa_function_pool[26059]: RenderMode (offset 196) */
    "i\0"
    "glRenderMode\0"
    "\0"
-   /* _mesa_function_pool[25857]: GetMapControlPointsNV (dynamic) */
+   /* _mesa_function_pool[26075]: GetMapControlPointsNV (dynamic) */
    "iiiiiip\0"
    "glGetMapControlPointsNV\0"
    "\0"
-   /* _mesa_function_pool[25890]: DrawBuffersARB (will be remapped) */
+   /* _mesa_function_pool[26108]: DrawBuffersARB (will be remapped) */
    "ip\0"
    "glDrawBuffers\0"
    "glDrawBuffersARB\0"
    "glDrawBuffersATI\0"
    "\0"
-   /* _mesa_function_pool[25942]: ProgramLocalParameter4fARB (will be remapped) */
+   /* _mesa_function_pool[26160]: ProgramLocalParameter4fARB (will be remapped) */
    "iiffff\0"
    "glProgramLocalParameter4fARB\0"
    "\0"
-   /* _mesa_function_pool[25979]: SpriteParameterivSGIX (dynamic) */
+   /* _mesa_function_pool[26197]: SpriteParameterivSGIX (dynamic) */
    "ip\0"
    "glSpriteParameterivSGIX\0"
    "\0"
-   /* _mesa_function_pool[26007]: ProvokingVertexEXT (will be remapped) */
+   /* _mesa_function_pool[26225]: ProvokingVertexEXT (will be remapped) */
    "i\0"
    "glProvokingVertexEXT\0"
    "glProvokingVertex\0"
    "\0"
-   /* _mesa_function_pool[26049]: MultiTexCoord1fARB (offset 378) */
+   /* _mesa_function_pool[26267]: MultiTexCoord1fARB (offset 378) */
    "if\0"
    "glMultiTexCoord1f\0"
    "glMultiTexCoord1fARB\0"
    "\0"
-   /* _mesa_function_pool[26092]: LoadName (offset 198) */
+   /* _mesa_function_pool[26310]: LoadName (offset 198) */
    "i\0"
    "glLoadName\0"
    "\0"
-   /* _mesa_function_pool[26106]: VertexAttribs4ubvNV (will be remapped) */
+   /* _mesa_function_pool[26324]: VertexAttribs4ubvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4ubvNV\0"
    "\0"
-   /* _mesa_function_pool[26133]: WeightsvARB (dynamic) */
+   /* _mesa_function_pool[26351]: WeightsvARB (dynamic) */
    "ip\0"
    "glWeightsvARB\0"
    "\0"
-   /* _mesa_function_pool[26151]: Uniform1fvARB (will be remapped) */
+   /* _mesa_function_pool[26369]: Uniform1fvARB (will be remapped) */
    "iip\0"
    "glUniform1fv\0"
    "glUniform1fvARB\0"
    "\0"
-   /* _mesa_function_pool[26185]: CopyTexSubImage1D (offset 325) */
+   /* _mesa_function_pool[26403]: CopyTexSubImage1D (offset 325) */
    "iiiiii\0"
    "glCopyTexSubImage1D\0"
    "glCopyTexSubImage1DEXT\0"
    "\0"
-   /* _mesa_function_pool[26236]: CullFace (offset 152) */
+   /* _mesa_function_pool[26454]: CullFace (offset 152) */
    "i\0"
    "glCullFace\0"
    "\0"
-   /* _mesa_function_pool[26250]: BindTexture (offset 307) */
+   /* _mesa_function_pool[26468]: BindTexture (offset 307) */
    "ii\0"
    "glBindTexture\0"
    "glBindTextureEXT\0"
    "\0"
-   /* _mesa_function_pool[26285]: BeginFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[26503]: BeginFragmentShaderATI (will be remapped) */
    "\0"
    "glBeginFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[26312]: MultiTexCoord4fARB (offset 402) */
+   /* _mesa_function_pool[26530]: MultiTexCoord4fARB (offset 402) */
    "iffff\0"
    "glMultiTexCoord4f\0"
    "glMultiTexCoord4fARB\0"
    "\0"
-   /* _mesa_function_pool[26358]: VertexAttribs3svNV (will be remapped) */
+   /* _mesa_function_pool[26576]: VertexAttribs3svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs3svNV\0"
    "\0"
-   /* _mesa_function_pool[26384]: StencilFunc (offset 243) */
+   /* _mesa_function_pool[26602]: StencilFunc (offset 243) */
    "iii\0"
    "glStencilFunc\0"
    "\0"
-   /* _mesa_function_pool[26403]: CopyPixels (offset 255) */
+   /* _mesa_function_pool[26621]: CopyPixels (offset 255) */
    "iiiii\0"
    "glCopyPixels\0"
    "\0"
-   /* _mesa_function_pool[26423]: Rectsv (offset 93) */
+   /* _mesa_function_pool[26641]: Rectsv (offset 93) */
    "pp\0"
    "glRectsv\0"
    "\0"
-   /* _mesa_function_pool[26436]: ReplacementCodeuivSUN (dynamic) */
+   /* _mesa_function_pool[26654]: ReplacementCodeuivSUN (dynamic) */
    "p\0"
    "glReplacementCodeuivSUN\0"
    "\0"
-   /* _mesa_function_pool[26463]: EnableVertexAttribArrayARB (will be remapped) */
+   /* _mesa_function_pool[26681]: EnableVertexAttribArrayARB (will be remapped) */
    "i\0"
    "glEnableVertexAttribArray\0"
    "glEnableVertexAttribArrayARB\0"
    "\0"
-   /* _mesa_function_pool[26521]: NormalPointervINTEL (dynamic) */
+   /* _mesa_function_pool[26739]: NormalPointervINTEL (dynamic) */
    "ip\0"
    "glNormalPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[26547]: CopyConvolutionFilter2D (offset 355) */
+   /* _mesa_function_pool[26765]: CopyConvolutionFilter2D (offset 355) */
    "iiiiii\0"
    "glCopyConvolutionFilter2D\0"
    "glCopyConvolutionFilter2DEXT\0"
    "\0"
-   /* _mesa_function_pool[26610]: WindowPos3ivMESA (will be remapped) */
+   /* _mesa_function_pool[26828]: WindowPos3ivMESA (will be remapped) */
    "p\0"
    "glWindowPos3iv\0"
    "glWindowPos3ivARB\0"
    "glWindowPos3ivMESA\0"
    "\0"
-   /* _mesa_function_pool[26665]: CopyBufferSubData (will be remapped) */
+   /* _mesa_function_pool[26883]: CopyBufferSubData (will be remapped) */
    "iiiii\0"
    "glCopyBufferSubData\0"
    "\0"
-   /* _mesa_function_pool[26692]: NormalPointer (offset 318) */
+   /* _mesa_function_pool[26910]: NormalPointer (offset 318) */
    "iip\0"
    "glNormalPointer\0"
    "\0"
-   /* _mesa_function_pool[26713]: TexParameterfv (offset 179) */
+   /* _mesa_function_pool[26931]: TexParameterfv (offset 179) */
    "iip\0"
    "glTexParameterfv\0"
    "\0"
-   /* _mesa_function_pool[26735]: IsBufferARB (will be remapped) */
+   /* _mesa_function_pool[26953]: IsBufferARB (will be remapped) */
    "i\0"
    "glIsBuffer\0"
    "glIsBufferARB\0"
    "\0"
-   /* _mesa_function_pool[26763]: WindowPos4iMESA (will be remapped) */
+   /* _mesa_function_pool[26981]: WindowPos4iMESA (will be remapped) */
    "iiii\0"
    "glWindowPos4iMESA\0"
    "\0"
-   /* _mesa_function_pool[26787]: VertexAttrib4uivARB (will be remapped) */
+   /* _mesa_function_pool[27005]: VertexAttrib4uivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4uiv\0"
    "glVertexAttrib4uivARB\0"
    "\0"
-   /* _mesa_function_pool[26832]: Tangent3bvEXT (dynamic) */
+   /* _mesa_function_pool[27050]: Tangent3bvEXT (dynamic) */
    "p\0"
    "glTangent3bvEXT\0"
    "\0"
-   /* _mesa_function_pool[26851]: UniformMatrix3x4fv (will be remapped) */
+   /* _mesa_function_pool[27069]: UniformMatrix3x4fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix3x4fv\0"
    "\0"
-   /* _mesa_function_pool[26878]: ClipPlane (offset 150) */
+   /* _mesa_function_pool[27096]: ClipPlane (offset 150) */
    "ip\0"
    "glClipPlane\0"
    "\0"
-   /* _mesa_function_pool[26894]: Recti (offset 90) */
+   /* _mesa_function_pool[27112]: Recti (offset 90) */
    "iiii\0"
    "glRecti\0"
    "\0"
-   /* _mesa_function_pool[26908]: DrawRangeElementsBaseVertex (will be remapped) */
+   /* _mesa_function_pool[27126]: DrawRangeElementsBaseVertex (will be remapped) */
    "iiiiipi\0"
    "glDrawRangeElementsBaseVertex\0"
    "\0"
-   /* _mesa_function_pool[26947]: TexCoordPointervINTEL (dynamic) */
+   /* _mesa_function_pool[27165]: TexCoordPointervINTEL (dynamic) */
    "iip\0"
    "glTexCoordPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[26976]: DeleteBuffersARB (will be remapped) */
+   /* _mesa_function_pool[27194]: DeleteBuffersARB (will be remapped) */
    "ip\0"
    "glDeleteBuffers\0"
    "glDeleteBuffersARB\0"
    "\0"
-   /* _mesa_function_pool[27015]: WindowPos4fvMESA (will be remapped) */
+   /* _mesa_function_pool[27233]: WindowPos4fvMESA (will be remapped) */
    "p\0"
    "glWindowPos4fvMESA\0"
    "\0"
-   /* _mesa_function_pool[27037]: GetPixelMapuiv (offset 272) */
+   /* _mesa_function_pool[27255]: GetPixelMapuiv (offset 272) */
    "ip\0"
    "glGetPixelMapuiv\0"
    "\0"
-   /* _mesa_function_pool[27058]: Rectf (offset 88) */
+   /* _mesa_function_pool[27276]: Rectf (offset 88) */
    "ffff\0"
    "glRectf\0"
    "\0"
-   /* _mesa_function_pool[27072]: VertexAttrib1sNV (will be remapped) */
+   /* _mesa_function_pool[27290]: VertexAttrib1sNV (will be remapped) */
    "ii\0"
    "glVertexAttrib1sNV\0"
    "\0"
-   /* _mesa_function_pool[27095]: Indexfv (offset 47) */
+   /* _mesa_function_pool[27313]: Indexfv (offset 47) */
    "p\0"
    "glIndexfv\0"
    "\0"
-   /* _mesa_function_pool[27108]: SecondaryColor3svEXT (will be remapped) */
+   /* _mesa_function_pool[27326]: SecondaryColor3svEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3sv\0"
    "glSecondaryColor3svEXT\0"
    "\0"
-   /* _mesa_function_pool[27154]: LoadTransposeMatrixfARB (will be remapped) */
+   /* _mesa_function_pool[27372]: LoadTransposeMatrixfARB (will be remapped) */
    "p\0"
    "glLoadTransposeMatrixf\0"
    "glLoadTransposeMatrixfARB\0"
    "\0"
-   /* _mesa_function_pool[27206]: GetPointerv (offset 329) */
+   /* _mesa_function_pool[27424]: GetPointerv (offset 329) */
    "ip\0"
    "glGetPointerv\0"
    "glGetPointervEXT\0"
    "\0"
-   /* _mesa_function_pool[27241]: Tangent3bEXT (dynamic) */
+   /* _mesa_function_pool[27459]: Tangent3bEXT (dynamic) */
    "iii\0"
    "glTangent3bEXT\0"
    "\0"
-   /* _mesa_function_pool[27261]: CombinerParameterfNV (will be remapped) */
+   /* _mesa_function_pool[27479]: CombinerParameterfNV (will be remapped) */
    "if\0"
    "glCombinerParameterfNV\0"
    "\0"
-   /* _mesa_function_pool[27288]: IndexMask (offset 212) */
+   /* _mesa_function_pool[27506]: IndexMask (offset 212) */
    "i\0"
    "glIndexMask\0"
    "\0"
-   /* _mesa_function_pool[27303]: BindProgramNV (will be remapped) */
+   /* _mesa_function_pool[27521]: BindProgramNV (will be remapped) */
    "ii\0"
    "glBindProgramARB\0"
    "glBindProgramNV\0"
    "\0"
-   /* _mesa_function_pool[27340]: VertexAttrib4svARB (will be remapped) */
+   /* _mesa_function_pool[27558]: VertexAttrib4svARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4sv\0"
    "glVertexAttrib4svARB\0"
    "\0"
-   /* _mesa_function_pool[27383]: GetFloatv (offset 262) */
+   /* _mesa_function_pool[27601]: GetFloatv (offset 262) */
    "ip\0"
    "glGetFloatv\0"
    "\0"
-   /* _mesa_function_pool[27399]: CreateDebugObjectMESA (dynamic) */
+   /* _mesa_function_pool[27617]: CreateDebugObjectMESA (dynamic) */
    "\0"
    "glCreateDebugObjectMESA\0"
    "\0"
-   /* _mesa_function_pool[27425]: GetShaderiv (will be remapped) */
+   /* _mesa_function_pool[27643]: GetShaderiv (will be remapped) */
    "iip\0"
    "glGetShaderiv\0"
    "\0"
-   /* _mesa_function_pool[27444]: ClientWaitSync (will be remapped) */
+   /* _mesa_function_pool[27662]: ClientWaitSync (will be remapped) */
    "iii\0"
    "glClientWaitSync\0"
    "\0"
-   /* _mesa_function_pool[27466]: TexCoord4s (offset 124) */
+   /* _mesa_function_pool[27684]: TexCoord4s (offset 124) */
    "iiii\0"
    "glTexCoord4s\0"
    "\0"
-   /* _mesa_function_pool[27485]: TexCoord3sv (offset 117) */
+   /* _mesa_function_pool[27703]: TexCoord3sv (offset 117) */
    "p\0"
    "glTexCoord3sv\0"
    "\0"
-   /* _mesa_function_pool[27502]: BindFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[27720]: BindFragmentShaderATI (will be remapped) */
    "i\0"
    "glBindFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[27529]: PopAttrib (offset 218) */
+   /* _mesa_function_pool[27747]: PopAttrib (offset 218) */
    "\0"
    "glPopAttrib\0"
    "\0"
-   /* _mesa_function_pool[27543]: Fogfv (offset 154) */
+   /* _mesa_function_pool[27761]: Fogfv (offset 154) */
    "ip\0"
    "glFogfv\0"
    "\0"
-   /* _mesa_function_pool[27555]: UnmapBufferARB (will be remapped) */
+   /* _mesa_function_pool[27773]: UnmapBufferARB (will be remapped) */
    "i\0"
    "glUnmapBuffer\0"
    "glUnmapBufferARB\0"
    "\0"
-   /* _mesa_function_pool[27589]: InitNames (offset 197) */
+   /* _mesa_function_pool[27807]: InitNames (offset 197) */
    "\0"
    "glInitNames\0"
    "\0"
-   /* _mesa_function_pool[27603]: Normal3sv (offset 61) */
+   /* _mesa_function_pool[27821]: Normal3sv (offset 61) */
    "p\0"
    "glNormal3sv\0"
    "\0"
-   /* _mesa_function_pool[27618]: Minmax (offset 368) */
+   /* _mesa_function_pool[27836]: Minmax (offset 368) */
    "iii\0"
    "glMinmax\0"
    "glMinmaxEXT\0"
    "\0"
-   /* _mesa_function_pool[27644]: TexCoord4d (offset 118) */
+   /* _mesa_function_pool[27862]: TexCoord4d (offset 118) */
    "dddd\0"
    "glTexCoord4d\0"
    "\0"
-   /* _mesa_function_pool[27663]: TexCoord4f (offset 120) */
+   /* _mesa_function_pool[27881]: TexCoord4f (offset 120) */
    "ffff\0"
    "glTexCoord4f\0"
    "\0"
-   /* _mesa_function_pool[27682]: FogCoorddvEXT (will be remapped) */
+   /* _mesa_function_pool[27900]: FogCoorddvEXT (will be remapped) */
    "p\0"
    "glFogCoorddv\0"
    "glFogCoorddvEXT\0"
    "\0"
-   /* _mesa_function_pool[27714]: FinishTextureSUNX (dynamic) */
+   /* _mesa_function_pool[27932]: FinishTextureSUNX (dynamic) */
    "\0"
    "glFinishTextureSUNX\0"
    "\0"
-   /* _mesa_function_pool[27736]: GetFragmentLightfvSGIX (dynamic) */
+   /* _mesa_function_pool[27954]: GetFragmentLightfvSGIX (dynamic) */
    "iip\0"
    "glGetFragmentLightfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[27766]: Binormal3fvEXT (dynamic) */
+   /* _mesa_function_pool[27984]: Binormal3fvEXT (dynamic) */
    "p\0"
    "glBinormal3fvEXT\0"
    "\0"
-   /* _mesa_function_pool[27786]: GetBooleanv (offset 258) */
+   /* _mesa_function_pool[28004]: GetBooleanv (offset 258) */
    "ip\0"
    "glGetBooleanv\0"
    "\0"
-   /* _mesa_function_pool[27804]: ColorFragmentOp3ATI (will be remapped) */
+   /* _mesa_function_pool[28022]: ColorFragmentOp3ATI (will be remapped) */
    "iiiiiiiiiiiii\0"
    "glColorFragmentOp3ATI\0"
    "\0"
-   /* _mesa_function_pool[27841]: Hint (offset 158) */
+   /* _mesa_function_pool[28059]: Hint (offset 158) */
    "ii\0"
    "glHint\0"
    "\0"
-   /* _mesa_function_pool[27852]: Color4dv (offset 28) */
+   /* _mesa_function_pool[28070]: Color4dv (offset 28) */
    "p\0"
    "glColor4dv\0"
    "\0"
-   /* _mesa_function_pool[27866]: VertexAttrib2svARB (will be remapped) */
+   /* _mesa_function_pool[28084]: VertexAttrib2svARB (will be remapped) */
    "ip\0"
    "glVertexAttrib2sv\0"
    "glVertexAttrib2svARB\0"
    "\0"
-   /* _mesa_function_pool[27909]: AreProgramsResidentNV (will be remapped) */
+   /* _mesa_function_pool[28127]: AreProgramsResidentNV (will be remapped) */
    "ipp\0"
    "glAreProgramsResidentNV\0"
    "\0"
-   /* _mesa_function_pool[27938]: WindowPos3svMESA (will be remapped) */
+   /* _mesa_function_pool[28156]: WindowPos3svMESA (will be remapped) */
    "p\0"
    "glWindowPos3sv\0"
    "glWindowPos3svARB\0"
    "glWindowPos3svMESA\0"
    "\0"
-   /* _mesa_function_pool[27993]: CopyColorSubTable (offset 347) */
+   /* _mesa_function_pool[28211]: CopyColorSubTable (offset 347) */
    "iiiii\0"
    "glCopyColorSubTable\0"
    "glCopyColorSubTableEXT\0"
    "\0"
-   /* _mesa_function_pool[28043]: WeightdvARB (dynamic) */
+   /* _mesa_function_pool[28261]: WeightdvARB (dynamic) */
    "ip\0"
    "glWeightdvARB\0"
    "\0"
-   /* _mesa_function_pool[28061]: DeleteRenderbuffersEXT (will be remapped) */
+   /* _mesa_function_pool[28279]: DeleteRenderbuffersEXT (will be remapped) */
    "ip\0"
    "glDeleteRenderbuffers\0"
    "glDeleteRenderbuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[28112]: VertexAttrib4NubvARB (will be remapped) */
+   /* _mesa_function_pool[28330]: VertexAttrib4NubvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nubv\0"
    "glVertexAttrib4NubvARB\0"
    "\0"
-   /* _mesa_function_pool[28159]: VertexAttrib3dvNV (will be remapped) */
+   /* _mesa_function_pool[28377]: VertexAttrib3dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib3dvNV\0"
    "\0"
-   /* _mesa_function_pool[28183]: GetObjectParameterfvARB (will be remapped) */
+   /* _mesa_function_pool[28401]: GetObjectParameterfvARB (will be remapped) */
    "iip\0"
    "glGetObjectParameterfvARB\0"
    "\0"
-   /* _mesa_function_pool[28214]: Vertex4iv (offset 147) */
+   /* _mesa_function_pool[28432]: Vertex4iv (offset 147) */
    "p\0"
    "glVertex4iv\0"
    "\0"
-   /* _mesa_function_pool[28229]: GetProgramEnvParameterdvARB (will be remapped) */
+   /* _mesa_function_pool[28447]: GetProgramEnvParameterdvARB (will be remapped) */
    "iip\0"
    "glGetProgramEnvParameterdvARB\0"
    "\0"
-   /* _mesa_function_pool[28264]: TexCoord4dv (offset 119) */
+   /* _mesa_function_pool[28482]: TexCoord4dv (offset 119) */
    "p\0"
    "glTexCoord4dv\0"
    "\0"
-   /* _mesa_function_pool[28281]: LockArraysEXT (will be remapped) */
+   /* _mesa_function_pool[28499]: LockArraysEXT (will be remapped) */
    "ii\0"
    "glLockArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[28301]: Begin (offset 7) */
+   /* _mesa_function_pool[28519]: Begin (offset 7) */
    "i\0"
    "glBegin\0"
    "\0"
-   /* _mesa_function_pool[28312]: LightModeli (offset 165) */
+   /* _mesa_function_pool[28530]: LightModeli (offset 165) */
    "ii\0"
    "glLightModeli\0"
    "\0"
-   /* _mesa_function_pool[28330]: Rectfv (offset 89) */
+   /* _mesa_function_pool[28548]: Rectfv (offset 89) */
    "pp\0"
    "glRectfv\0"
    "\0"
-   /* _mesa_function_pool[28343]: LightModelf (offset 163) */
+   /* _mesa_function_pool[28561]: LightModelf (offset 163) */
    "if\0"
    "glLightModelf\0"
    "\0"
-   /* _mesa_function_pool[28361]: GetTexParameterfv (offset 282) */
+   /* _mesa_function_pool[28579]: GetTexParameterfv (offset 282) */
    "iip\0"
    "glGetTexParameterfv\0"
    "\0"
-   /* _mesa_function_pool[28386]: GetLightfv (offset 264) */
+   /* _mesa_function_pool[28604]: GetLightfv (offset 264) */
    "iip\0"
    "glGetLightfv\0"
    "\0"
-   /* _mesa_function_pool[28404]: PixelTransformParameterivEXT (dynamic) */
+   /* _mesa_function_pool[28622]: PixelTransformParameterivEXT (dynamic) */
    "iip\0"
    "glPixelTransformParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[28440]: BinormalPointerEXT (dynamic) */
+   /* _mesa_function_pool[28658]: BinormalPointerEXT (dynamic) */
    "iip\0"
    "glBinormalPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[28466]: VertexAttrib1dNV (will be remapped) */
+   /* _mesa_function_pool[28684]: VertexAttrib1dNV (will be remapped) */
    "id\0"
    "glVertexAttrib1dNV\0"
    "\0"
-   /* _mesa_function_pool[28489]: GetCombinerInputParameterivNV (will be remapped) */
+   /* _mesa_function_pool[28707]: GetCombinerInputParameterivNV (will be remapped) */
    "iiiip\0"
    "glGetCombinerInputParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[28528]: Disable (offset 214) */
+   /* _mesa_function_pool[28746]: Disable (offset 214) */
    "i\0"
    "glDisable\0"
    "\0"
-   /* _mesa_function_pool[28541]: MultiTexCoord2fvARB (offset 387) */
+   /* _mesa_function_pool[28759]: MultiTexCoord2fvARB (offset 387) */
    "ip\0"
    "glMultiTexCoord2fv\0"
    "glMultiTexCoord2fvARB\0"
    "\0"
-   /* _mesa_function_pool[28586]: GetRenderbufferParameterivEXT (will be remapped) */
+   /* _mesa_function_pool[28804]: GetRenderbufferParameterivEXT (will be remapped) */
    "iip\0"
    "glGetRenderbufferParameteriv\0"
    "glGetRenderbufferParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[28652]: CombinerParameterivNV (will be remapped) */
+   /* _mesa_function_pool[28870]: CombinerParameterivNV (will be remapped) */
    "ip\0"
    "glCombinerParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[28680]: GenFragmentShadersATI (will be remapped) */
+   /* _mesa_function_pool[28898]: GenFragmentShadersATI (will be remapped) */
    "i\0"
    "glGenFragmentShadersATI\0"
    "\0"
-   /* _mesa_function_pool[28707]: DrawArrays (offset 310) */
+   /* _mesa_function_pool[28925]: DrawArrays (offset 310) */
    "iii\0"
    "glDrawArrays\0"
    "glDrawArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[28741]: WeightuivARB (dynamic) */
+   /* _mesa_function_pool[28959]: WeightuivARB (dynamic) */
    "ip\0"
    "glWeightuivARB\0"
    "\0"
-   /* _mesa_function_pool[28760]: VertexAttrib2sARB (will be remapped) */
+   /* _mesa_function_pool[28978]: VertexAttrib2sARB (will be remapped) */
    "iii\0"
    "glVertexAttrib2s\0"
    "glVertexAttrib2sARB\0"
    "\0"
-   /* _mesa_function_pool[28802]: ColorMask (offset 210) */
+   /* _mesa_function_pool[29020]: ColorMask (offset 210) */
    "iiii\0"
    "glColorMask\0"
    "\0"
-   /* _mesa_function_pool[28820]: GenAsyncMarkersSGIX (dynamic) */
+   /* _mesa_function_pool[29038]: GenAsyncMarkersSGIX (dynamic) */
    "i\0"
    "glGenAsyncMarkersSGIX\0"
    "\0"
-   /* _mesa_function_pool[28845]: Tangent3svEXT (dynamic) */
+   /* _mesa_function_pool[29063]: Tangent3svEXT (dynamic) */
    "p\0"
    "glTangent3svEXT\0"
    "\0"
-   /* _mesa_function_pool[28864]: GetListParameterivSGIX (dynamic) */
+   /* _mesa_function_pool[29082]: GetListParameterivSGIX (dynamic) */
    "iip\0"
    "glGetListParameterivSGIX\0"
    "\0"
-   /* _mesa_function_pool[28894]: BindBufferARB (will be remapped) */
+   /* _mesa_function_pool[29112]: BindBufferARB (will be remapped) */
    "ii\0"
    "glBindBuffer\0"
    "glBindBufferARB\0"
    "\0"
-   /* _mesa_function_pool[28927]: GetInfoLogARB (will be remapped) */
+   /* _mesa_function_pool[29145]: GetInfoLogARB (will be remapped) */
    "iipp\0"
    "glGetInfoLogARB\0"
    "\0"
-   /* _mesa_function_pool[28949]: RasterPos4iv (offset 83) */
+   /* _mesa_function_pool[29167]: RasterPos4iv (offset 83) */
    "p\0"
    "glRasterPos4iv\0"
    "\0"
-   /* _mesa_function_pool[28967]: Enable (offset 215) */
+   /* _mesa_function_pool[29185]: Enable (offset 215) */
    "i\0"
    "glEnable\0"
    "\0"
-   /* _mesa_function_pool[28979]: LineStipple (offset 167) */
+   /* _mesa_function_pool[29197]: LineStipple (offset 167) */
    "ii\0"
    "glLineStipple\0"
    "\0"
-   /* _mesa_function_pool[28997]: VertexAttribs4svNV (will be remapped) */
+   /* _mesa_function_pool[29215]: VertexAttribs4svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4svNV\0"
    "\0"
-   /* _mesa_function_pool[29023]: EdgeFlagPointerListIBM (dynamic) */
+   /* _mesa_function_pool[29241]: EdgeFlagPointerListIBM (dynamic) */
    "ipi\0"
    "glEdgeFlagPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[29053]: UniformMatrix3x2fv (will be remapped) */
+   /* _mesa_function_pool[29271]: UniformMatrix3x2fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix3x2fv\0"
    "\0"
-   /* _mesa_function_pool[29080]: GetMinmaxParameterfv (offset 365) */
+   /* _mesa_function_pool[29298]: GetMinmaxParameterfv (offset 365) */
    "iip\0"
    "glGetMinmaxParameterfv\0"
    "glGetMinmaxParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[29134]: VertexAttrib1fvARB (will be remapped) */
+   /* _mesa_function_pool[29352]: VertexAttrib1fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib1fv\0"
    "glVertexAttrib1fvARB\0"
    "\0"
-   /* _mesa_function_pool[29177]: GenBuffersARB (will be remapped) */
+   /* _mesa_function_pool[29395]: GenBuffersARB (will be remapped) */
    "ip\0"
    "glGenBuffers\0"
    "glGenBuffersARB\0"
    "\0"
-   /* _mesa_function_pool[29210]: VertexAttribs1svNV (will be remapped) */
+   /* _mesa_function_pool[29428]: VertexAttribs1svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs1svNV\0"
    "\0"
-   /* _mesa_function_pool[29236]: Vertex3fv (offset 137) */
+   /* _mesa_function_pool[29454]: Vertex3fv (offset 137) */
    "p\0"
    "glVertex3fv\0"
    "\0"
-   /* _mesa_function_pool[29251]: GetTexBumpParameterivATI (will be remapped) */
+   /* _mesa_function_pool[29469]: GetTexBumpParameterivATI (will be remapped) */
    "ip\0"
    "glGetTexBumpParameterivATI\0"
    "\0"
-   /* _mesa_function_pool[29282]: Binormal3bEXT (dynamic) */
+   /* _mesa_function_pool[29500]: Binormal3bEXT (dynamic) */
    "iii\0"
    "glBinormal3bEXT\0"
    "\0"
-   /* _mesa_function_pool[29303]: FragmentMaterialivSGIX (dynamic) */
+   /* _mesa_function_pool[29521]: FragmentMaterialivSGIX (dynamic) */
    "iip\0"
    "glFragmentMaterialivSGIX\0"
    "\0"
-   /* _mesa_function_pool[29333]: IsRenderbufferEXT (will be remapped) */
+   /* _mesa_function_pool[29551]: IsRenderbufferEXT (will be remapped) */
    "i\0"
    "glIsRenderbuffer\0"
    "glIsRenderbufferEXT\0"
    "\0"
-   /* _mesa_function_pool[29373]: GenProgramsNV (will be remapped) */
+   /* _mesa_function_pool[29591]: GenProgramsNV (will be remapped) */
    "ip\0"
    "glGenProgramsARB\0"
    "glGenProgramsNV\0"
    "\0"
-   /* _mesa_function_pool[29410]: VertexAttrib4dvNV (will be remapped) */
+   /* _mesa_function_pool[29628]: VertexAttrib4dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib4dvNV\0"
    "\0"
-   /* _mesa_function_pool[29434]: EndFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[29652]: EndFragmentShaderATI (will be remapped) */
    "\0"
    "glEndFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[29459]: Binormal3iEXT (dynamic) */
+   /* _mesa_function_pool[29677]: Binormal3iEXT (dynamic) */
    "iii\0"
    "glBinormal3iEXT\0"
    "\0"
-   /* _mesa_function_pool[29480]: WindowPos2fMESA (will be remapped) */
+   /* _mesa_function_pool[29698]: WindowPos2fMESA (will be remapped) */
    "ff\0"
    "glWindowPos2f\0"
    "glWindowPos2fARB\0"
@@ -4334,392 +4366,400 @@
    GLint remap_index;
 } MESA_remap_table_functions[] = {
    {  1461, AttachShader_remap_index },
-   {  8704, CreateProgram_remap_index },
-   { 20158, CreateShader_remap_index },
-   { 22418, DeleteProgram_remap_index },
-   { 16193, DeleteShader_remap_index },
-   { 20604, DetachShader_remap_index },
-   { 15717, 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 },
-   { 27425, GetShaderiv_remap_index },
-   { 11732, IsProgram_remap_index },
-   { 10767, 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 },
-   { 19535, UniformMatrix2x3fv_remap_index },
+   {  6654, StencilOpSeparate_remap_index },
+   { 19653, UniformMatrix2x3fv_remap_index },
    {  2615, UniformMatrix2x4fv_remap_index },
-   { 29053, UniformMatrix3x2fv_remap_index },
-   { 26851, UniformMatrix3x4fv_remap_index },
-   { 14265, UniformMatrix4x2fv_remap_index },
+   { 29271, UniformMatrix3x2fv_remap_index },
+   { 27069, UniformMatrix3x4fv_remap_index },
+   { 14354, UniformMatrix4x2fv_remap_index },
    {  2937, UniformMatrix4x3fv_remap_index },
-   {  8722, LoadTransposeMatrixdARB_remap_index },
-   { 27154, LoadTransposeMatrixfARB_remap_index },
-   {  4817, MultTransposeMatrixdARB_remap_index },
-   { 20791, 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 },
-   { 21248, CompressedTexImage2DARB_remap_index },
+   {  5002, CompressedTexImage1DARB_remap_index },
+   { 21392, CompressedTexImage2DARB_remap_index },
    {  3550, CompressedTexImage3DARB_remap_index },
-   { 16009, CompressedTexSubImage1DARB_remap_index },
+   { 16098, CompressedTexSubImage1DARB_remap_index },
    {  1880, CompressedTexSubImage2DARB_remap_index },
-   { 17801, CompressedTexSubImage3DARB_remap_index },
-   { 25133, GetCompressedTexImageARB_remap_index },
+   { 17890, CompressedTexSubImage3DARB_remap_index },
+   { 25351, GetCompressedTexImageARB_remap_index },
    {  3395, DisableVertexAttribArrayARB_remap_index },
-   { 26463, EnableVertexAttribArrayARB_remap_index },
-   { 28229, GetProgramEnvParameterdvARB_remap_index },
-   { 20671, GetProgramEnvParameterfvARB_remap_index },
-   { 24163, GetProgramLocalParameterdvARB_remap_index },
-   {  7065, GetProgramLocalParameterfvARB_remap_index },
-   { 16100, GetProgramStringARB_remap_index },
-   { 24358, GetProgramivARB_remap_index },
-   { 17996, GetVertexAttribdvARB_remap_index },
-   { 14154, GetVertexAttribfvARB_remap_index },
-   {  8617, GetVertexAttribivARB_remap_index },
-   { 16905, ProgramEnvParameter4dARB_remap_index },
-   { 22218, ProgramEnvParameter4dvARB_remap_index },
-   { 14762, 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 },
-   { 11442, ProgramLocalParameter4dvARB_remap_index },
-   { 25942, ProgramLocalParameter4fARB_remap_index },
-   { 22736, ProgramLocalParameter4fvARB_remap_index },
-   { 24919, ProgramStringARB_remap_index },
-   { 17155, VertexAttrib1dARB_remap_index },
-   { 13808, 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 },
-   { 29134, VertexAttrib1fvARB_remap_index },
-   {  6149, VertexAttrib1sARB_remap_index },
+   { 29352, VertexAttrib1fvARB_remap_index },
+   {  6180, VertexAttrib1sARB_remap_index },
    {  2054, VertexAttrib1svARB_remap_index },
-   { 13239, VertexAttrib2dARB_remap_index },
-   { 15336, VertexAttrib2dvARB_remap_index },
+   { 13328, VertexAttrib2dARB_remap_index },
+   { 15425, VertexAttrib2dvARB_remap_index },
    {  1480, VertexAttrib2fARB_remap_index },
-   { 15449, VertexAttrib2fvARB_remap_index },
-   { 28760, VertexAttrib2sARB_remap_index },
-   { 27866, 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 },
-   { 19772, VertexAttrib3fvARB_remap_index },
-   { 24791, VertexAttrib3sARB_remap_index },
-   { 17738, VertexAttrib3svARB_remap_index },
-   {  4270, VertexAttrib4NbvARB_remap_index },
-   { 15672, VertexAttrib4NivARB_remap_index },
-   { 19727, VertexAttrib4NsvARB_remap_index },
-   { 20623, VertexAttrib4NubARB_remap_index },
-   { 28112, VertexAttrib4NubvARB_remap_index },
-   { 16566, 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 },
-   { 23571, VertexAttrib4dARB_remap_index },
-   { 18721, VertexAttrib4dvARB_remap_index },
-   { 10033, VertexAttrib4fARB_remap_index },
-   { 10403, VertexAttrib4fvARB_remap_index },
-   {  9001, VertexAttrib4ivARB_remap_index },
-   { 15150, VertexAttrib4sARB_remap_index },
-   { 27340, VertexAttrib4svARB_remap_index },
-   { 14567, VertexAttrib4ubvARB_remap_index },
-   { 26787, VertexAttrib4uivARB_remap_index },
-   { 17549, VertexAttrib4usvARB_remap_index },
-   { 19409, VertexAttribPointerARB_remap_index },
-   { 28894, 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 },
-   { 26976, DeleteBuffersARB_remap_index },
-   { 29177, GenBuffersARB_remap_index },
-   { 15492, GetBufferParameterivARB_remap_index },
-   { 14714, GetBufferPointervARB_remap_index },
+   { 27194, DeleteBuffersARB_remap_index },
+   { 29395, GenBuffersARB_remap_index },
+   { 15581, GetBufferParameterivARB_remap_index },
+   { 14803, GetBufferPointervARB_remap_index },
    {  1335, GetBufferSubDataARB_remap_index },
-   { 26735, IsBufferARB_remap_index },
-   { 23167, MapBufferARB_remap_index },
-   { 27555, UnmapBufferARB_remap_index },
+   { 26953, IsBufferARB_remap_index },
+   { 23362, MapBufferARB_remap_index },
+   { 27773, UnmapBufferARB_remap_index },
    {   268, BeginQueryARB_remap_index },
-   { 17250, DeleteQueriesARB_remap_index },
-   { 10664, EndQueryARB_remap_index },
-   { 25612, GenQueriesARB_remap_index },
+   { 17339, DeleteQueriesARB_remap_index },
+   { 10753, EndQueryARB_remap_index },
+   { 25830, GenQueriesARB_remap_index },
    {  1772, GetQueryObjectivARB_remap_index },
-   { 15194, GetQueryObjectuivARB_remap_index },
+   { 15283, GetQueryObjectuivARB_remap_index },
    {  1624, GetQueryivARB_remap_index },
-   { 17456, IsQueryARB_remap_index },
-   {  7241, AttachObjectARB_remap_index },
-   { 16155, CompileShaderARB_remap_index },
+   { 17545, IsQueryARB_remap_index },
+   {  7272, AttachObjectARB_remap_index },
+   { 16244, CompileShaderARB_remap_index },
    {  2879, CreateProgramObjectARB_remap_index },
-   {  5807, CreateShaderObjectARB_remap_index },
-   { 12656, DeleteObjectARB_remap_index },
-   { 21022, DetachObjectARB_remap_index },
-   { 10475, GetActiveUniformARB_remap_index },
-   {  8320, GetAttachedObjectsARB_remap_index },
-   {  8599, GetHandleARB_remap_index },
-   { 28927, GetInfoLogARB_remap_index },
-   { 28183, GetObjectParameterfvARB_remap_index },
-   { 24037, GetObjectParameterivARB_remap_index },
-   { 25370, GetShaderSourceARB_remap_index },
-   { 24651, GetUniformLocationARB_remap_index },
-   { 20893, GetUniformfvARB_remap_index },
-   { 11064, GetUniformivARB_remap_index },
-   { 17594, LinkProgramARB_remap_index },
-   { 17652, ShaderSourceARB_remap_index },
-   {  6523, Uniform1fARB_remap_index },
-   { 26151, Uniform1fvARB_remap_index },
-   { 19378, Uniform1iARB_remap_index },
-   { 18410, 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 },
-   { 12492, Uniform2fvARB_remap_index },
-   { 23054, Uniform2iARB_remap_index },
+   { 12581, Uniform2fvARB_remap_index },
+   { 23249, Uniform2iARB_remap_index },
    {  2123, Uniform2ivARB_remap_index },
-   { 16265, Uniform3fARB_remap_index },
-   {  8350, Uniform3fvARB_remap_index },
-   {  5481, Uniform3iARB_remap_index },
-   { 14820, Uniform3ivARB_remap_index },
-   { 16711, Uniform4fARB_remap_index },
-   { 20757, Uniform4fvARB_remap_index },
-   { 21897, Uniform4iARB_remap_index },
-   { 17962, 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 },
-   { 22330, UseProgramObjectARB_remap_index },
-   { 12927, ValidateProgramARB_remap_index },
-   { 18764, BindAttribLocationARB_remap_index },
-   {  4315, GetActiveAttribARB_remap_index },
-   { 14501, GetAttribLocationARB_remap_index },
-   { 25890, DrawBuffersARB_remap_index },
-   { 11547, RenderbufferStorageMultisample_remap_index },
-   { 16759, FlushMappedBufferRange_remap_index },
-   { 24454, MapBufferRange_remap_index },
-   { 14376, BindVertexArray_remap_index },
-   { 12786, GenVertexArrays_remap_index },
-   { 26665, CopyBufferSubData_remap_index },
-   { 27444, 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 },
-   { 13298, GetInteger64v_remap_index },
-   { 19834, GetSynciv_remap_index },
-   { 25829, 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 },
-   { 26908, DrawRangeElementsBaseVertex_remap_index },
-   { 23198, MultiDrawElementsBaseVertex_remap_index },
-   {  4680, PolygonOffsetEXT_remap_index },
-   { 20393, GetPixelTexGenParameterfvSGIS_remap_index },
+   { 27126, DrawRangeElementsBaseVertex_remap_index },
+   { 23393, MultiDrawElementsBaseVertex_remap_index },
+   {  4711, PolygonOffsetEXT_remap_index },
+   { 20537, GetPixelTexGenParameterfvSGIS_remap_index },
    {  3895, GetPixelTexGenParameterivSGIS_remap_index },
-   { 20126, PixelTexGenParameterfSGIS_remap_index },
+   { 20270, PixelTexGenParameterfSGIS_remap_index },
    {   580, PixelTexGenParameterfvSGIS_remap_index },
-   { 11102, PixelTexGenParameteriSGIS_remap_index },
-   { 12063, PixelTexGenParameterivSGIS_remap_index },
-   { 14464, SampleMaskSGIS_remap_index },
-   { 17396, SamplePatternSGIS_remap_index },
-   { 23127, ColorPointerEXT_remap_index },
-   { 15379, EdgeFlagPointerEXT_remap_index },
-   {  5135, IndexPointerEXT_remap_index },
-   {  5215, NormalPointerEXT_remap_index },
-   { 13892, 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 },
-   { 28281, LockArraysEXT_remap_index },
-   { 12991, 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 },
-   { 22476, SecondaryColor3dvEXT_remap_index },
-   { 24700, SecondaryColor3fEXT_remap_index },
-   { 15945, 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 },
-   { 14202, SecondaryColor3ivEXT_remap_index },
-   {  8836, SecondaryColor3sEXT_remap_index },
-   { 27108, SecondaryColor3svEXT_remap_index },
-   { 23873, SecondaryColor3ubEXT_remap_index },
-   { 18655, SecondaryColor3ubvEXT_remap_index },
-   { 11297, SecondaryColor3uiEXT_remap_index },
-   { 20013, SecondaryColor3uivEXT_remap_index },
-   { 22688, SecondaryColor3usEXT_remap_index },
-   { 11370, SecondaryColor3usvEXT_remap_index },
-   { 10346, SecondaryColorPointerEXT_remap_index },
-   { 22537, MultiDrawArraysEXT_remap_index },
-   { 18345, MultiDrawElementsEXT_remap_index },
-   { 18540, 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 },
-   { 27682, FogCoorddvEXT_remap_index },
-   {  4105, FogCoordfEXT_remap_index },
-   { 23796, FogCoordfvEXT_remap_index },
-   { 16663, PixelTexGenSGIX_remap_index },
-   { 24381, BlendFuncSeparateEXT_remap_index },
-   {  5897, FlushVertexArrayRangeNV_remap_index },
-   {  4629, VertexArrayRangeNV_remap_index },
-   { 24765, 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 },
-   { 27261, CombinerParameterfNV_remap_index },
-   {  4549, CombinerParameterfvNV_remap_index },
-   { 19584, CombinerParameteriNV_remap_index },
-   { 28652, CombinerParameterivNV_remap_index },
-   {  6267, FinalCombinerInputNV_remap_index },
-   {  8665, GetCombinerInputParameterfvNV_remap_index },
-   { 28489, GetCombinerInputParameterivNV_remap_index },
-   {  6066, GetCombinerOutputParameterfvNV_remap_index },
-   { 12024, GetCombinerOutputParameterivNV_remap_index },
-   {  5642, GetFinalCombinerInputParameterfvNV_remap_index },
-   { 21769, GetFinalCombinerInputParameterivNV_remap_index },
-   { 11042, 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 },
-   { 29480, WindowPos2fMESA_remap_index },
-   {  6934, WindowPos2fvMESA_remap_index },
-   { 15892, WindowPos2iMESA_remap_index },
-   { 17869, WindowPos2ivMESA_remap_index },
-   { 18444, WindowPos2sMESA_remap_index },
-   {  4885, WindowPos2svMESA_remap_index },
-   {  6759, WindowPos3dMESA_remap_index },
-   { 12271, 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 },
-   { 13052, WindowPos3fvMESA_remap_index },
-   { 21064, WindowPos3iMESA_remap_index },
-   { 26610, WindowPos3ivMESA_remap_index },
-   { 16409, WindowPos3sMESA_remap_index },
-   { 27938, WindowPos3svMESA_remap_index },
-   {  9704, WindowPos4dMESA_remap_index },
-   { 14905, WindowPos4dvMESA_remap_index },
-   { 12230, WindowPos4fMESA_remap_index },
-   { 27015, WindowPos4fvMESA_remap_index },
-   { 26763, WindowPos4iMESA_remap_index },
-   { 10881, WindowPos4ivMESA_remap_index },
-   { 16542, 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 },
-   { 23539, MultiModeDrawArraysIBM_remap_index },
-   { 25483, MultiModeDrawElementsIBM_remap_index },
-   { 10692, DeleteFencesNV_remap_index },
-   { 24612, FinishFenceNV_remap_index },
+   { 23757, MultiModeDrawArraysIBM_remap_index },
+   { 25701, MultiModeDrawElementsIBM_remap_index },
+   { 10781, DeleteFencesNV_remap_index },
+   { 24830, FinishFenceNV_remap_index },
    {  3287, GenFencesNV_remap_index },
-   { 14885, GetFenceivNV_remap_index },
-   {  7226, IsFenceNV_remap_index },
-   { 11951, SetFenceNV_remap_index },
+   { 14974, GetFenceivNV_remap_index },
+   {  7257, IsFenceNV_remap_index },
+   { 12040, SetFenceNV_remap_index },
    {  3744, TestFenceNV_remap_index },
-   { 27909, AreProgramsResidentNV_remap_index },
-   { 27303, BindProgramNV_remap_index },
-   { 22771, DeleteProgramsNV_remap_index },
-   { 18873, ExecuteProgramNV_remap_index },
-   { 29373, GenProgramsNV_remap_index },
-   { 20472, GetProgramParameterdvNV_remap_index },
-   {  9240, GetProgramParameterfvNV_remap_index },
-   { 23101, GetProgramStringNV_remap_index },
-   { 21458, GetProgramivNV_remap_index },
-   { 20706, GetTrackMatrixivNV_remap_index },
-   { 22921, GetVertexAttribPointervNV_remap_index },
-   { 21702, GetVertexAttribdvNV_remap_index },
-   { 16382, GetVertexAttribfvNV_remap_index },
-   { 16073, GetVertexAttribivNV_remap_index },
-   { 16789, IsProgramNV_remap_index },
-   {  8246, LoadProgramNV_remap_index },
-   { 24477, ProgramParameters4dvNV_remap_index },
-   { 21388, ProgramParameters4fvNV_remap_index },
-   { 18173, RequestResidentProgramsNV_remap_index },
-   { 19562, TrackMatrixNV_remap_index },
-   { 28466, VertexAttrib1dNV_remap_index },
-   { 11892, VertexAttrib1dvNV_remap_index },
-   { 25015, 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 },
-   { 27072, VertexAttrib1sNV_remap_index },
-   { 13125, VertexAttrib1svNV_remap_index },
-   {  4220, VertexAttrib2dNV_remap_index },
-   { 11807, VertexAttrib2dvNV_remap_index },
-   { 17628, VertexAttrib2fNV_remap_index },
-   { 11418, VertexAttrib2fvNV_remap_index },
-   {  5045, VertexAttrib2sNV_remap_index },
-   { 16463, VertexAttrib2svNV_remap_index },
-   {  9901, VertexAttrib3dNV_remap_index },
-   { 28159, VertexAttrib3dvNV_remap_index },
-   {  9052, VertexAttrib3fNV_remap_index },
-   { 21729, VertexAttrib3fvNV_remap_index },
-   { 24990, VertexAttrib3sNV_remap_index },
-   { 20733, VertexAttrib3svNV_remap_index },
-   { 25457, VertexAttrib4dNV_remap_index },
-   { 29410, 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 },
-   { 23423, 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 },
-   { 19053, VertexAttribPointerNV_remap_index },
+   { 19142, VertexAttribPointerNV_remap_index },
    {  2097, VertexAttribs1dvNV_remap_index },
-   { 16487, VertexAttribs1fvNV_remap_index },
-   { 29210, VertexAttribs1svNV_remap_index },
-   {  9077, VertexAttribs2dvNV_remap_index },
-   { 22291, VertexAttribs2fvNV_remap_index },
-   { 15405, 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 },
-   { 26358, VertexAttribs3svNV_remap_index },
-   { 23513, VertexAttribs4dvNV_remap_index },
-   {  4603, VertexAttribs4fvNV_remap_index },
-   { 28997, VertexAttribs4svNV_remap_index },
-   { 26106, VertexAttribs4ubvNV_remap_index },
-   { 23615, GetTexBumpParameterfvATI_remap_index },
-   { 29251, GetTexBumpParameterivATI_remap_index },
-   { 16127, TexBumpParameterfvATI_remap_index },
-   { 18044, TexBumpParameterivATI_remap_index },
-   { 13671, AlphaFragmentOp1ATI_remap_index },
-   {  9592, AlphaFragmentOp2ATI_remap_index },
-   { 21645, AlphaFragmentOp3ATI_remap_index },
-   { 26285, BeginFragmentShaderATI_remap_index },
-   { 27502, BindFragmentShaderATI_remap_index },
-   { 20862, 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 },
-   { 27804, ColorFragmentOp3ATI_remap_index },
-   {  4722, DeleteFragmentShaderATI_remap_index },
-   { 29434, EndFragmentShaderATI_remap_index },
-   { 28680, GenFragmentShadersATI_remap_index },
-   { 22395, 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 },
-   { 12432, PointParameterivNV_remap_index },
-   { 25296, ActiveStencilFaceEXT_remap_index },
-   { 24137, BindVertexArrayAPPLE_remap_index },
+   { 12521, PointParameterivNV_remap_index },
+   { 25514, ActiveStencilFaceEXT_remap_index },
+   { 24355, BindVertexArrayAPPLE_remap_index },
    {  2522, DeleteVertexArraysAPPLE_remap_index },
-   { 15744, GenVertexArraysAPPLE_remap_index },
-   { 20537, IsVertexArrayAPPLE_remap_index },
+   { 15833, GenVertexArraysAPPLE_remap_index },
+   { 20681, IsVertexArrayAPPLE_remap_index },
    {   775, GetProgramNamedParameterdvNV_remap_index },
    {  3128, GetProgramNamedParameterfvNV_remap_index },
-   { 23646, ProgramNamedParameter4dNV_remap_index },
-   { 12707, ProgramNamedParameter4dvNV_remap_index },
-   {  7862, ProgramNamedParameter4fNV_remap_index },
-   { 10311, ProgramNamedParameter4fvNV_remap_index },
-   { 21367, 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 },
-   { 12826, BindFramebufferEXT_remap_index },
-   { 22582, BindRenderbufferEXT_remap_index },
-   {  8515, CheckFramebufferStatusEXT_remap_index },
-   { 19853, DeleteFramebuffersEXT_remap_index },
-   { 28061, DeleteRenderbuffersEXT_remap_index },
-   { 11831, FramebufferRenderbufferEXT_remap_index },
-   { 11968, FramebufferTexture1DEXT_remap_index },
-   { 10139, FramebufferTexture2DEXT_remap_index },
-   {  9806, FramebufferTexture3DEXT_remap_index },
-   { 20429, GenFramebuffersEXT_remap_index },
-   { 15291, GenRenderbuffersEXT_remap_index },
-   {  5684, GenerateMipmapEXT_remap_index },
-   { 19084, GetFramebufferAttachmentParameterivEXT_remap_index },
-   { 28586, GetRenderbufferParameterivEXT_remap_index },
-   { 17924, IsFramebufferEXT_remap_index },
-   { 29333, 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 },
-   { 12526, BufferParameteriAPPLE_remap_index },
-   { 16821, FlushMappedBufferRangeAPPLE_remap_index },
+   { 12615, BufferParameteriAPPLE_remap_index },
+   { 16910, FlushMappedBufferRangeAPPLE_remap_index },
    {  2701, FramebufferTextureLayerEXT_remap_index },
-   { 26007, ProvokingVertexEXT_remap_index },
-   {  9461, GetTexParameterPointervAPPLE_remap_index },
-   {  4405, TextureRangeAPPLE_remap_index },
-   { 25322, StencilFuncSeparateATI_remap_index },
-   { 15811, ProgramEnvParameters4fvEXT_remap_index },
-   { 15029, ProgramLocalParameters4fvEXT_remap_index },
-   { 12360, 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 }
 };
 
@@ -4728,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 */
-   { 14927, _gloffset_ColorSubTable },
-   { 27993, _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 },
-   { 18072, _gloffset_GetSeparableFilter },
-   { 21118, _gloffset_SeparableFilter2D },
-   { 21947, _gloffset_ConvolutionParameteri },
-   { 22070, _gloffset_ConvolutionParameterf },
-   { 23449, _gloffset_GetConvolutionParameterfv },
-   { 24303, _gloffset_GetConvolutionFilter },
-   { 26547, _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 */
-   { 13185, _gloffset_CopyTexSubImage3D },
-   { 14667, _gloffset_CopyTexImage2D },
-   { 21555, _gloffset_CopyTexImage1D },
-   { 23984, _gloffset_CopyTexSubImage2D },
-   { 26185, _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 },
-   { 13519, _gloffset_GetHistogramParameterfv },
-   { 21480, _gloffset_GetMinmaxParameteriv },
-   { 23339, _gloffset_ResetMinmax },
-   { 24200, _gloffset_GetHistogramParameteriv },
-   { 25256, _gloffset_GetHistogram },
-   { 27618, _gloffset_Minmax },
-   { 29080, _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 },
-   { 13365, _gloffset_GetColorTable },
-   { 20176, _gloffset_GetColorTableParameterfv },
-   { 22126, _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 },
-   { 19945, _gloffset_TexSubImage3D },
+   { 20089, _gloffset_TexSubImage3D },
    /* from GL_EXT_texture_object */
    {  2964, _gloffset_PrioritizeTextures },
-   {  6554, _gloffset_AreTexturesResident },
-   { 11916, _gloffset_GenTextures },
-   { 13851, _gloffset_DeleteTextures },
-   { 17102, _gloffset_IsTexture },
-   { 26250, _gloffset_BindTexture },
+   {  6585, _gloffset_AreTexturesResident },
+   { 12005, _gloffset_GenTextures },
+   { 13940, _gloffset_DeleteTextures },
+   { 17191, _gloffset_IsTexture },
+   { 26468, _gloffset_BindTexture },
    /* from GL_EXT_vertex_array */
-   { 21307, _gloffset_ArrayElement },
-   { 27206, _gloffset_GetPointerv },
-   { 28707, _gloffset_DrawArrays },
+   { 21451, _gloffset_ArrayElement },
+   { 27424, _gloffset_GetPointerv },
+   { 28925, _gloffset_DrawArrays },
    /* from GL_SGI_color_table */
-   {  6672, _gloffset_ColorTableParameteriv },
-   {  7384, _gloffset_ColorTable },
-   { 13365, _gloffset_GetColorTable },
-   { 13475, _gloffset_CopyColorTable },
-   { 16963, _gloffset_ColorTableParameterfv },
-   { 20176, _gloffset_GetColorTableParameterfv },
-   { 22126, _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 },
-   { 10903, _gloffset_MultiTexCoord3svARB },
-   { 10964, _gloffset_MultiTexCoord4iARB },
-   { 11687, _gloffset_MultiTexCoord3iARB },
-   { 12389, _gloffset_MultiTexCoord1dARB },
-   { 12555, _gloffset_MultiTexCoord3dvARB },
-   { 13719, _gloffset_MultiTexCoord3ivARB },
-   { 13764, _gloffset_MultiTexCoord2sARB },
-   { 14984, _gloffset_MultiTexCoord4ivARB },
-   { 16613, _gloffset_ClientActiveTextureARB },
-   { 18829, _gloffset_MultiTexCoord2dARB },
-   { 19204, _gloffset_MultiTexCoord4dvARB },
-   { 19490, _gloffset_MultiTexCoord4fvARB },
-   { 20317, _gloffset_MultiTexCoord3fARB },
-   { 22627, _gloffset_MultiTexCoord4dARB },
-   { 22831, _gloffset_MultiTexCoord1sARB },
-   { 23009, _gloffset_MultiTexCoord1dvARB },
-   { 23828, _gloffset_MultiTexCoord1ivARB },
-   { 23921, _gloffset_MultiTexCoord2ivARB },
-   { 24260, _gloffset_MultiTexCoord1iARB },
-   { 25531, _gloffset_MultiTexCoord4svARB },
-   { 26049, _gloffset_MultiTexCoord1fARB },
-   { 26312, _gloffset_MultiTexCoord4fARB },
-   { 28541, _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 }
 };
 
@@ -4837,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
@@ -4901,10 +4941,10 @@
 #if defined(need_GL_ARB_matrix_palette)
 static const struct gl_function_remap GL_ARB_matrix_palette_functions[] = {
    {  3339, -1 }, /* MatrixIndexusvARB */
-   { 11508, -1 }, /* MatrixIndexuivARB */
-   { 12677, -1 }, /* MatrixIndexPointerARB */
-   { 17351, -1 }, /* CurrentPaletteMatrixARB */
-   { 20061, -1 }, /* MatrixIndexubvARB */
+   { 11597, -1 }, /* MatrixIndexuivARB */
+   { 12766, -1 }, /* MatrixIndexPointerARB */
+   { 17440, -1 }, /* CurrentPaletteMatrixARB */
+   { 20205, -1 }, /* MatrixIndexubvARB */
    {    -1, -1 }
 };
 #endif
@@ -4975,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 */
-   { 12146, -1 }, /* WeightfvARB */
-   { 15431, -1 }, /* WeightbvARB */
-   { 18497, -1 }, /* WeightusvARB */
-   { 21044, -1 }, /* VertexBlendARB */
-   { 26133, -1 }, /* WeightsvARB */
-   { 28043, -1 }, /* WeightdvARB */
-   { 28741, -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
@@ -5074,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[] = {
-   { 14927, _gloffset_ColorSubTable },
-   { 27993, _gloffset_CopyColorSubTable },
+   { 15016, _gloffset_ColorSubTable },
+   { 28211, _gloffset_CopyColorSubTable },
    {    -1, -1 }
 };
 #endif
@@ -5099,55 +5139,55 @@
    {   213, _gloffset_ConvolutionFilter1D },
    {  2284, _gloffset_CopyConvolutionFilter1D },
    {  3624, _gloffset_GetConvolutionParameteriv },
-   {  7522, _gloffset_ConvolutionFilter2D },
-   {  7688, _gloffset_ConvolutionParameteriv },
-   {  8148, _gloffset_ConvolutionParameterfv },
-   { 18072, _gloffset_GetSeparableFilter },
-   { 21118, _gloffset_SeparableFilter2D },
-   { 21947, _gloffset_ConvolutionParameteri },
-   { 22070, _gloffset_ConvolutionParameterf },
-   { 23449, _gloffset_GetConvolutionParameterfv },
-   { 24303, _gloffset_GetConvolutionFilter },
-   { 26547, _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 */
-   { 11022, -1 }, /* Binormal3ivEXT */
-   { 11640, -1 }, /* Tangent3sEXT */
-   { 12742, -1 }, /* Tangent3fvEXT */
-   { 16363, -1 }, /* Tangent3dvEXT */
-   { 17049, -1 }, /* Binormal3bvEXT */
-   { 18125, -1 }, /* Binormal3dEXT */
-   { 19993, -1 }, /* Tangent3fEXT */
-   { 22019, -1 }, /* Binormal3sEXT */
-   { 22437, -1 }, /* Tangent3ivEXT */
-   { 22456, -1 }, /* Tangent3dEXT */
-   { 23236, -1 }, /* Binormal3svEXT */
-   { 23726, -1 }, /* Binormal3fEXT */
-   { 24578, -1 }, /* Binormal3dvEXT */
-   { 25753, -1 }, /* Tangent3iEXT */
-   { 26832, -1 }, /* Tangent3bvEXT */
-   { 27241, -1 }, /* Tangent3bEXT */
-   { 27766, -1 }, /* Binormal3fvEXT */
-   { 28440, -1 }, /* BinormalPointerEXT */
-   { 28845, -1 }, /* Tangent3svEXT */
-   { 29282, -1 }, /* Binormal3bEXT */
-   { 29459, -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[] = {
-   { 13185, _gloffset_CopyTexSubImage3D },
-   { 14667, _gloffset_CopyTexImage2D },
-   { 21555, _gloffset_CopyTexImage1D },
-   { 23984, _gloffset_CopyTexSubImage2D },
-   { 26185, _gloffset_CopyTexSubImage1D },
+   { 13274, _gloffset_CopyTexSubImage3D },
+   { 14756, _gloffset_CopyTexImage2D },
+   { 21699, _gloffset_CopyTexImage1D },
+   { 24202, _gloffset_CopyTexSubImage2D },
+   { 26403, _gloffset_CopyTexSubImage1D },
    {    -1, -1 }
 };
 #endif
@@ -5166,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
@@ -5212,37 +5259,37 @@
 static const struct gl_function_remap GL_EXT_histogram_functions[] = {
    {   812, _gloffset_Histogram },
    {  3088, _gloffset_ResetHistogram },
-   {  8774, _gloffset_GetMinmax },
-   { 13519, _gloffset_GetHistogramParameterfv },
-   { 21480, _gloffset_GetMinmaxParameteriv },
-   { 23339, _gloffset_ResetMinmax },
-   { 24200, _gloffset_GetHistogramParameteriv },
-   { 25256, _gloffset_GetHistogram },
-   { 27618, _gloffset_Minmax },
-   { 29080, _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[] = {
-   { 18584, -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[] = {
-   { 23256, -1 }, /* ApplyTextureEXT */
-   { 23293, -1 }, /* TextureMaterialEXT */
-   { 23318, -1 }, /* TextureLightEXT */
+   { 23451, -1 }, /* ApplyTextureEXT */
+   { 23511, -1 }, /* TextureMaterialEXT */
+   { 23536, -1 }, /* TextureLightEXT */
    {    -1, -1 }
 };
 #endif
@@ -5263,20 +5310,20 @@
 
 #if defined(need_GL_EXT_paletted_texture)
 static const struct gl_function_remap GL_EXT_paletted_texture_functions[] = {
-   {  7384, _gloffset_ColorTable },
-   { 13365, _gloffset_GetColorTable },
-   { 20176, _gloffset_GetColorTableParameterfv },
-   { 22126, _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 */
-   { 19169, -1 }, /* PixelTransformParameterfEXT */
-   { 19249, -1 }, /* PixelTransformParameteriEXT */
-   { 28404, -1 }, /* PixelTransformParameterivEXT */
+   {  9573, -1 }, /* PixelTransformParameterfvEXT */
+   { 19287, -1 }, /* PixelTransformParameterfEXT */
+   { 19367, -1 }, /* PixelTransformParameteriEXT */
+   { 28622, -1 }, /* PixelTransformParameterivEXT */
    {    -1, -1 }
 };
 #endif
@@ -5318,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
@@ -5327,7 +5374,7 @@
 #if defined(need_GL_EXT_texture3D)
 static const struct gl_function_remap GL_EXT_texture3D_functions[] = {
    {  1658, _gloffset_TexImage3D },
-   { 19945, _gloffset_TexSubImage3D },
+   { 20089, _gloffset_TexSubImage3D },
    {    -1, -1 }
 };
 #endif
@@ -5342,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 },
-   { 11916, _gloffset_GenTextures },
-   { 13851, _gloffset_DeleteTextures },
-   { 17102, _gloffset_IsTexture },
-   { 26250, _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[] = {
-   { 12096, -1 }, /* TextureNormalEXT */
+   { 12185, -1 }, /* TextureNormalEXT */
    {    -1, -1 }
 };
 #endif
@@ -5368,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[] = {
-   { 21307, _gloffset_ArrayElement },
-   { 27206, _gloffset_GetPointerv },
-   { 28707, _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[] = {
-   { 17132, -1 }, /* VertexWeightfvEXT */
-   { 23704, -1 }, /* VertexWeightfEXT */
-   { 25225, -1 }, /* VertexWeightPointerEXT */
+   { 17221, -1 }, /* VertexWeightfvEXT */
+   { 23922, -1 }, /* VertexWeightfEXT */
+   { 25443, -1 }, /* VertexWeightPointerEXT */
    {    -1, -1 }
 };
 #endif
@@ -5388,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 */
-   { 10793, -1 }, /* GetImageTransformParameterivHP */
-   { 17196, -1 }, /* ImageTransformParameterivHP */
+   {  9026, -1 }, /* ImageTransformParameterfvHP */
+   { 10614, -1 }, /* ImageTransformParameteriHP */
+   { 10882, -1 }, /* GetImageTransformParameterivHP */
+   { 17285, -1 }, /* ImageTransformParameterivHP */
    {    -1, -1 }
 };
 #endif
@@ -5406,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 */
-   { 11747, -1 }, /* TexCoordPointerListIBM */
-   { 12118, -1 }, /* IndexPointerListIBM */
-   { 29023, -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
@@ -5426,10 +5473,10 @@
 
 #if defined(need_GL_INTEL_parallel_arrays)
 static const struct gl_function_remap GL_INTEL_parallel_arrays_functions[] = {
-   { 11134, -1 }, /* VertexPointervINTEL */
-   { 13612, -1 }, /* ColorPointervINTEL */
-   { 26521, -1 }, /* NormalPointervINTEL */
-   { 26947, -1 }, /* TexCoordPointervINTEL */
+   { 11223, -1 }, /* VertexPointervINTEL */
+   { 13701, -1 }, /* ColorPointervINTEL */
+   { 26739, -1 }, /* NormalPointervINTEL */
+   { 27165, -1 }, /* TexCoordPointervINTEL */
    {    -1, -1 }
 };
 #endif
@@ -5446,7 +5493,7 @@
    {  1522, -1 }, /* GetDebugLogLengthMESA */
    {  3063, -1 }, /* ClearDebugLogMESA */
    {  4018, -1 }, /* GetDebugLogMESA */
-   { 27399, -1 }, /* CreateDebugObjectMESA */
+   { 27617, -1 }, /* CreateDebugObjectMESA */
    {    -1, -1 }
 };
 #endif
@@ -5458,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 */
-   { 15101, -1 }, /* GetMapAttribParameterfvNV */
-   { 15267, -1 }, /* MapParameterivNV */
-   { 21870, -1 }, /* GetMapParameterivNV */
-   { 22368, -1 }, /* GetMapParameterfvNV */
-   { 25857, -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
@@ -5503,8 +5557,8 @@
 
 #if defined(need_GL_NV_register_combiners2)
 static const struct gl_function_remap GL_NV_register_combiners2_functions[] = {
-   { 14004, -1 }, /* CombinerStageParameterfvNV */
-   { 14319, -1 }, /* GetCombinerStageParameterfvNV */
+   { 14093, -1 }, /* CombinerStageParameterfvNV */
+   { 14408, -1 }, /* GetCombinerStageParameterfvNV */
    {    -1, -1 }
 };
 #endif
@@ -5525,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[] = {
-   { 14292, -1 }, /* GetDetailTexFuncSGIS */
-   { 14612, -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[] = {
-   { 23966, -1 }, /* FogFuncSGIS */
-   { 24631, -1 }, /* GetFogFuncSGIS */
+   { 24184, -1 }, /* FogFuncSGIS */
+   { 24849, -1 }, /* GetFogFuncSGIS */
    {    -1, -1 }
 };
 #endif
@@ -5569,8 +5623,8 @@
 
 #if defined(need_GL_SGIS_sharpen_texture)
 static const struct gl_function_remap GL_SGIS_sharpen_texture_functions[] = {
-   {  5834, -1 }, /* GetSharpenTexFuncSGIS */
-   { 19464, -1 }, /* SharpenTexFuncSGIS */
+   {  5865, -1 }, /* GetSharpenTexFuncSGIS */
+   { 19582, -1 }, /* SharpenTexFuncSGIS */
    {    -1, -1 }
 };
 #endif
@@ -5578,22 +5632,22 @@
 #if defined(need_GL_SGIS_texture4D)
 static const struct gl_function_remap GL_SGIS_texture4D_functions[] = {
    {   894, -1 }, /* TexImage4DSGIS */
-   { 13920, -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[] = {
-   { 13318, -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 */
-   { 14438, -1 }, /* TexFilterFuncSGIS */
+   {  6042, -1 }, /* GetTexFilterFuncSGIS */
+   { 14527, -1 }, /* TexFilterFuncSGIS */
    {    -1, -1 }
 };
 #endif
@@ -5602,17 +5656,17 @@
 static const struct gl_function_remap GL_SGIX_async_functions[] = {
    {  3014, -1 }, /* AsyncMarkerSGIX */
    {  3997, -1 }, /* FinishAsyncSGIX */
-   {  4703, -1 }, /* PollAsyncSGIX */
-   { 19611, -1 }, /* DeleteAsyncMarkersSGIX */
-   { 19640, -1 }, /* IsAsyncMarkerSGIX */
-   { 28820, -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
@@ -5621,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 */
-   { 17019, -1 }, /* FragmentLightModelfSGIX */
-   { 17319, -1 }, /* FragmentColorMaterialSGIX */
-   { 17691, -1 }, /* FragmentMaterialiSGIX */
-   { 18912, -1 }, /* LightEnviSGIX */
-   { 20268, -1 }, /* FragmentLightModelfvSGIX */
-   { 20577, -1 }, /* FragmentLightfvSGIX */
-   { 25107, -1 }, /* FragmentLightfSGIX */
-   { 27736, -1 }, /* GetFragmentLightfvSGIX */
-   { 29303, -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[] = {
-   { 19663, -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[] = {
-   { 25415, -1 }, /* IglooInterfaceSGIX */
+   { 25633, -1 }, /* IglooInterfaceSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5658,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 */
-   { 11345, -1 }, /* StartInstrumentsSGIX */
-   { 14038, -1 }, /* StopInstrumentsSGIX */
-   { 15644, -1 }, /* InstrumentsBufferSGIX */
+   {  5621, -1 }, /* PollInstrumentsSGIX */
+   {  9392, -1 }, /* GetInstrumentsSGIX */
+   { 11434, -1 }, /* StartInstrumentsSGIX */
+   { 14127, -1 }, /* StopInstrumentsSGIX */
+   { 15733, -1 }, /* InstrumentsBufferSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5671,10 +5725,10 @@
 static const struct gl_function_remap GL_SGIX_list_priority_functions[] = {
    {  1125, -1 }, /* ListParameterfSGIX */
    {  2763, -1 }, /* GetListParameterfvSGIX */
-   { 15559, -1 }, /* ListParameteriSGIX */
-   { 16313, -1 }, /* ListParameterfvSGIX */
-   { 18318, -1 }, /* ListParameterivSGIX */
-   { 28864, -1 }, /* GetListParameterivSGIX */
+   { 15648, -1 }, /* ListParameteriSGIX */
+   { 16402, -1 }, /* ListParameterfvSGIX */
+   { 18407, -1 }, /* ListParameterivSGIX */
+   { 29082, -1 }, /* GetListParameterivSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5689,53 +5743,53 @@
 #if defined(need_GL_SGIX_polynomial_ffd)
 static const struct gl_function_remap GL_SGIX_polynomial_ffd_functions[] = {
    {  3251, -1 }, /* LoadIdentityDeformationMapSGIX */
-   { 10713, -1 }, /* DeformationMap3dSGIX */
-   { 14138, -1 }, /* DeformSGIX */
-   { 21419, -1 }, /* DeformationMap3fSGIX */
+   { 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[] = {
-   { 12869, -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 */
-   { 18146, -1 }, /* SpriteParameteriSGIX */
-   { 23373, -1 }, /* SpriteParameterfSGIX */
-   { 25979, -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[] = {
-   { 18205, -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 },
-   { 13365, _gloffset_GetColorTable },
-   { 13475, _gloffset_CopyColorTable },
-   { 16963, _gloffset_ColorTableParameterfv },
-   { 20176, _gloffset_GetColorTableParameterfv },
-   { 22126, _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[] = {
-   { 27714, -1 }, /* FinishTextureSUNX */
+   { 27932, -1 }, /* FinishTextureSUNX */
    {    -1, -1 }
 };
 #endif
@@ -5743,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 */
-   { 11660, -1 }, /* GlobalAlphaFactorfSUN */
-   { 11779, -1 }, /* GlobalAlphaFactorusSUN */
-   { 19902, -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[] = {
-   { 25791, -1 }, /* DrawMeshArraysSUN */
+   { 26009, -1 }, /* DrawMeshArraysSUN */
    {    -1, -1 }
 };
 #endif
@@ -5764,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 */
-   { 16684, -1 }, /* ReplacementCodeusvSUN */
-   { 16872, -1 }, /* ReplacementCodePointerSUN */
-   { 18229, -1 }, /* ReplacementCodeusSUN */
-   { 18976, -1 }, /* ReplacementCodeuiSUN */
-   { 26436, -1 }, /* ReplacementCodeuivSUN */
+   {  5485, -1 }, /* ReplacementCodeubvSUN */
+   { 16773, -1 }, /* ReplacementCodeusvSUN */
+   { 16961, -1 }, /* ReplacementCodePointerSUN */
+   { 18318, -1 }, /* ReplacementCodeusSUN */
+   { 19065, -1 }, /* ReplacementCodeuiSUN */
+   { 26654, -1 }, /* ReplacementCodeuivSUN */
    {    -1, -1 }
 };
 #endif
@@ -5783,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 */
-   { 11208, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fvSUN */
-   { 12600, -1 }, /* ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN */
-   { 13011, -1 }, /* TexCoord2fColor3fVertex3fSUN */
-   { 14063, -1 }, /* TexCoord4fColor4fNormal3fVertex4fSUN */
-   { 14397, -1 }, /* Color4ubVertex2fvSUN */
-   { 14637, -1 }, /* Normal3fVertex3fSUN */
-   { 15585, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fSUN */
-   { 15846, -1 }, /* TexCoord2fColor4fNormal3fVertex3fvSUN */
-   { 16513, -1 }, /* TexCoord2fVertex3fvSUN */
-   { 17289, -1 }, /* Color4ubVertex2fSUN */
-   { 17482, -1 }, /* ReplacementCodeuiColor4ubVertex3fSUN */
-   { 19335, -1 }, /* TexCoord2fColor4ubVertex3fSUN */
-   { 19682, -1 }, /* Normal3fVertex3fvSUN */
-   { 20085, -1 }, /* Color4fNormal3fVertex3fSUN */
-   { 20951, -1 }, /* ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN */
-   { 21171, -1 }, /* ReplacementCodeuiColor4ubVertex3fvSUN */
-   { 22874, -1 }, /* ReplacementCodeuiColor3fVertex3fSUN */
-   { 24082, -1 }, /* TexCoord4fVertex4fSUN */
-   { 24508, -1 }, /* TexCoord2fColor3fVertex3fvSUN */
-   { 24834, -1 }, /* ReplacementCodeuiNormal3fVertex3fvSUN */
-   { 24961, -1 }, /* TexCoord4fVertex4fvSUN */
-   { 25663, -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
@@ -5826,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 },
-   { 10903, _gloffset_MultiTexCoord3svARB },
-   { 10964, _gloffset_MultiTexCoord4iARB },
-   { 11687, _gloffset_MultiTexCoord3iARB },
-   { 12389, _gloffset_MultiTexCoord1dARB },
-   { 12555, _gloffset_MultiTexCoord3dvARB },
-   { 13719, _gloffset_MultiTexCoord3ivARB },
-   { 13764, _gloffset_MultiTexCoord2sARB },
-   { 14984, _gloffset_MultiTexCoord4ivARB },
-   { 16613, _gloffset_ClientActiveTextureARB },
-   { 18829, _gloffset_MultiTexCoord2dARB },
-   { 19204, _gloffset_MultiTexCoord4dvARB },
-   { 19490, _gloffset_MultiTexCoord4fvARB },
-   { 20317, _gloffset_MultiTexCoord3fARB },
-   { 22627, _gloffset_MultiTexCoord4dARB },
-   { 22831, _gloffset_MultiTexCoord1sARB },
-   { 23009, _gloffset_MultiTexCoord1dvARB },
-   { 23828, _gloffset_MultiTexCoord1ivARB },
-   { 23921, _gloffset_MultiTexCoord2ivARB },
-   { 24260, _gloffset_MultiTexCoord1iARB },
-   { 25531, _gloffset_MultiTexCoord4svARB },
-   { 26049, _gloffset_MultiTexCoord1fARB },
-   { 26312, _gloffset_MultiTexCoord4fARB },
-   { 28541, _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/texenvprogram.c b/src/mesa/main/texenvprogram.c
index f439d4a..499b733 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -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/texgetimage.c b/src/mesa/main/texgetimage.c
index ac467c4..d786c41 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -555,7 +555,8 @@
       _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);
+                (GLubyte *)texImage->Data + i * row_stride_stored,
+                row_stride);
       }
    }
 
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 237b6eb..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;
@@ -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 9e1a889..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;
 
@@ -577,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;
 
@@ -635,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;
 
@@ -679,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;
 
@@ -728,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 )
@@ -978,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) {
@@ -1016,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:
          {
@@ -1145,25 +1199,14 @@
 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;
-   }
-
-   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;
-   }
+    obj = get_texobj(ctx, target, GL_TRUE);
+    if (!obj)
+       return;
 
    _mesa_lock_texture(ctx, obj);
    switch (pname) {
@@ -1185,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]);
@@ -1316,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/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 1c5749f..d521569 100644
--- a/src/mesa/main/version.h
+++ b/src/mesa/main/version.h
@@ -1,9 +1,9 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.7.1
+ * Version:  7.8
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009-2010  VMware, Inc.  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"),
@@ -28,11 +28,14 @@
 #define VERSION_H
 
 
+#include "mtypes.h"
+
+
 /* Mesa version */
 #define MESA_MAJOR 7
-#define MESA_MINOR 7
-#define MESA_PATCH 1
-#define MESA_VERSION_STRING "7.7.1-DEVEL"
+#define MESA_MINOR 8
+#define MESA_PATCH 0
+#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 dd732b6..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"
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_mesa.h b/src/mesa/shader/grammar/grammar_mesa.h
deleted file mode 100644
index 6c92c58..0000000
--- a/src/mesa/shader/grammar/grammar_mesa.h
+++ /dev/null
@@ -1,43 +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.
- */
-
-#ifndef GRAMMAR_MESA_H
-#define GRAMMAR_MESA_H
-
-
-#include "main/imports.h"
-/* NOTE: include Mesa 3-D specific headers here */
-
-
-typedef GLuint grammar;
-typedef GLubyte byte;
-
-
-#define GRAMMAR_PORT_INCLUDE 1
-#include "grammar.h"
-#undef GRAMMAR_PORT_INCLUDE
-
-
-#endif
-
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/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 8b9466a..ce41173 100644
--- a/src/mesa/shader/prog_optimize.c
+++ b/src/mesa/shader/prog_optimize.c
@@ -111,7 +111,6 @@
    if (removeCount > 0) {
       GLint removeStart = removeEnd - removeCount + 1;
       _mesa_delete_instructions(prog, removeStart, removeCount);
-      removeStart = removeCount = 0; /* reset removal info */
    }
    return totalRemoved;
 }
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_compile.c b/src/mesa/shader/slang/slang_compile.c
index 57e3555..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;
 }
 
@@ -2458,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,
@@ -2491,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;
@@ -2511,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
       {
@@ -2554,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) {
@@ -2689,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)
 {
@@ -2774,7 +2852,12 @@
    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_emit.c b/src/mesa/shader/slang/slang_emit.c
index c0e4b27..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++;
@@ -551,6 +551,9 @@
                                        &srcRelAddr,
                                        NULL,
                                        NULL);
+               if (!inst) {
+                  return NULL;
+               }
 
                src[i] = &newSrc[i];
             }
@@ -948,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) */
@@ -957,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");
 
@@ -972,6 +981,9 @@
                                  n->Store,
                                  &zero,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
          inst_comment(inst, "Invert true/false");
       }
    }
@@ -1001,6 +1013,9 @@
                                     &srcStore0,
                                     &srcStore1,
                                     NULL);
+            if (!inst) {
+               return NULL;
+            }
             inst_comment(inst, "Begin struct/array comparison");
          }
          else {
@@ -1010,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;
+            }
          }
       }
 
@@ -1025,6 +1046,9 @@
                               &accTemp,
                               &accTemp,
                               NULL);
+      if (!inst) {
+         return NULL;
+      }
       inst_comment(inst, "End struct/array comparison");
 
       if (n->Opcode == IR_EQUAL) {
@@ -1036,6 +1060,9 @@
                                  n->Store,
                                  &zero,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
          inst_comment(inst, "Invert true/false");
       }
 
@@ -1119,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,
@@ -1153,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;
 }
 
@@ -1356,6 +1388,9 @@
                            n->Children[1]->Store,
                            NULL,
                            NULL);
+   if (!inst) {
+      return NULL;
+   }
 
    inst->TexShadow = shadow;
 
@@ -1458,6 +1493,9 @@
                                     &srcStore,
                                     NULL,
                                     NULL);
+            if (!inst) {
+               return NULL;
+            }
             inst_comment(inst, "IR_COPY block");
             srcStore.Index++;
             dstStore.Index++;
@@ -1473,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,
@@ -1534,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);
@@ -1596,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]);
@@ -1646,12 +1693,17 @@
          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 {
@@ -1676,6 +1728,7 @@
          if (!inst) {
             return NULL;
          }
+         prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions - 1;
       }
       else {
          /* jump to endif instruction */
@@ -1685,8 +1738,8 @@
          }
          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 {
@@ -1701,8 +1754,14 @@
       }
    }
 
-   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;
 }
@@ -1762,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;
@@ -1771,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 ||
@@ -1875,6 +1939,9 @@
                                  n->Children[0]->Store,
                                  NULL,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
          n->InstLocation = emitInfo->prog->NumInstructions;
 
          inst = new_instruction(emitInfo, opcode);
@@ -1887,7 +1954,7 @@
          }
 
          emitInfo->prog->Instructions[ifInstLoc].BranchTarget
-            = emitInfo->prog->NumInstructions;
+            = emitInfo->prog->NumInstructions - 1;
          return inst;
       }
    }
@@ -2045,6 +2112,9 @@
                                  indexStore, /* the index */
                                  &elemSizeStore,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
 
          indexStore = indexTemp;
       }
@@ -2071,6 +2141,9 @@
                                  indexStore,     /* the index */
                                  &indirectArray, /* indirect array base */
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
 
          indexStore = indexTemp;
       }
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 0a2bc49..ed27821 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -590,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];
@@ -606,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++) {
@@ -626,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;
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/sources.mak b/src/mesa/sources.mak
index a0d7dbb..c42f61a 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,6 +192,7 @@
 	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 \
@@ -218,7 +221,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 \
@@ -255,7 +257,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	\
@@ -365,6 +366,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 731ff2b..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)
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index 0e89a62..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,
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 9208f3f..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,168 +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 GLbitfield64 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
-      }
-
-      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 *
@@ -326,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);
@@ -360,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 1960d17..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;
 }
 
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/drivers/dri/intel/intel_swapbuffers.h b/src/mesa/state_tracker/st_cb_condrender.h
similarity index 66%
copy from src/mesa/drivers/dri/intel/intel_swapbuffers.h
copy to src/mesa/state_tracker/st_cb_condrender.h
index 75bb624..891f1cb 100644
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.h
+++ b/src/mesa/state_tracker/st_cb_condrender.h
@@ -1,7 +1,6 @@
-
 /**************************************************************************
  * 
- * Copyright 2006 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
@@ -19,34 +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 INTEL_SWAPBUFFERS_H
-#define INTEL_SWAPBUFFERS_H
-
-#include "dri_util.h"
-#include "drm.h"
-
-struct intel_context;
-struct intel_framebuffer;
+#ifndef ST_CB_CONDRENDER_H
+#define ST_CB_CONDRENDER_H
 
 
-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);
+extern void st_init_cond_render_functions(struct dd_function_table *functions);
 
 
-#endif /* INTEL_SWAPBUFFERS_H */
+#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_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 cb9106c..0cec23f 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"
 
@@ -204,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;
@@ -405,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);
@@ -634,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;
@@ -833,7 +833,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++) {
@@ -890,7 +890,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.
@@ -915,7 +915,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
@@ -1041,7 +1041,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;
@@ -1163,10 +1163,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);
@@ -1178,8 +1178,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);
@@ -1193,16 +1192,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) {
@@ -1266,7 +1265,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;
@@ -1692,10 +1691,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;
    }
@@ -1761,10 +1760,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 ||
-          stObj->pt->block.size != blockSize)
+          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_context.c b/src/mesa/state_tracker/st_context.c
index d18a25a..e4f18c8 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"
@@ -337,6 +338,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 5c6af11..e54f21b 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -217,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;
-   }
-}
 
 
 /**
@@ -279,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)
 {
@@ -288,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 */
@@ -321,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;
@@ -333,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;
@@ -373,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,
@@ -383,7 +334,7 @@
    GLuint attr;
    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);
@@ -394,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;
@@ -435,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,
@@ -444,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;
@@ -538,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.
@@ -555,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 = 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) {
@@ -586,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
@@ -633,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:
@@ -671,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);
          }
       }
@@ -698,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 57fe72d..35e0874 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);
 
@@ -302,4 +306,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 2785728..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
@@ -104,22 +98,22 @@
          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;
@@ -127,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 {
@@ -154,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" */
@@ -392,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
@@ -475,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 );
@@ -503,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 2d404d5..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);
@@ -235,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
@@ -272,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 0b7786c..e788008 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -408,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 )
@@ -631,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, 
@@ -688,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
@@ -706,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;
@@ -734,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);*/
 
@@ -760,6 +808,10 @@
          emit_inverted_wpos( t, program );
       }
 
+      if (program->InputsRead & FRAG_BIT_FACE) {
+         emit_face_var( t, program );
+      }
+
       /*
        * Declare output attributes.
        */
@@ -794,6 +846,8 @@
                                            outputSemanticName[i],
                                            outputSemanticIndex[i] );
       }
+      if (passthrough_edgeflags)
+         emit_edgeflags( t, program );
    }
 
    /* Declare address register.
@@ -866,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);
@@ -876,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 cf19f8f..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,31 +91,13 @@
  * \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);
@@ -95,162 +110,59 @@
     */
    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:
@@ -259,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);
@@ -352,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;
 }
 
 
@@ -375,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;
 
@@ -385,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;
@@ -434,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:
@@ -450,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];
       }
    }
 
@@ -500,8 +413,6 @@
                break;
             }
 
-            output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr];
-
             fs_num_outputs++;
          }
       }
@@ -510,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,
@@ -520,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_texture.c b/src/mesa/state_tracker/st_texture.c
index 10f1351..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;
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_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_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_span.c b/src/mesa/swrast/s_span.c
index 1a51d4f..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) {
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 5bec606..11184b7 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -1030,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 bd20a8d..8484aab 100644
--- a/src/mesa/swrast_setup/ss_tritmp.h
+++ b/src/mesa/swrast_setup/ss_tritmp.h
@@ -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.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 a9dae7d..15a8a67 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -461,19 +461,14 @@
       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];
    }
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 d568bfd..2424204 100644
--- a/src/mesa/tnl_dd/t_dd_dmatmp.h
+++ b/src/mesa/tnl_dd/t_dd_dmatmp.h
@@ -447,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();
@@ -1230,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_tritmp.h b/src/mesa/tnl_dd/t_dd_tritmp.h
index c3ba851..6acd837 100644
--- a/src/mesa/tnl_dd/t_dd_tritmp.h
+++ b/src/mesa/tnl_dd/t_dd_tritmp.h
@@ -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 );
 	 }
@@ -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/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 134cff7..bc83b5a 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)
diff --git a/src/mesa/x86/gen_matypes.c b/src/mesa/x86/gen_matypes.c
index 771d9df..14cfa91 100644
--- a/src/mesa/x86/gen_matypes.c
+++ b/src/mesa/x86/gen_matypes.c
@@ -110,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 0da924c..6668852 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)
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>