diff options
| author | marha <marha@users.sourceforge.net> | 2011-01-13 22:01:27 +0000 | 
|---|---|---|
| committer | marha <marha@users.sourceforge.net> | 2011-01-13 22:01:27 +0000 | 
| commit | a0a46bd55d7cbbf70757a29c067e21b70ac4e2df (patch) | |
| tree | 95803181a66e63d191b3fe06a031f9ed8ae701b8 | |
| parent | 2ebdcfeee38bed8c65daa78aa7d18d8d1d93ed85 (diff) | |
| download | vcxsrv-a0a46bd55d7cbbf70757a29c067e21b70ac4e2df.tar.gz vcxsrv-a0a46bd55d7cbbf70757a29c067e21b70ac4e2df.tar.bz2 vcxsrv-a0a46bd55d7cbbf70757a29c067e21b70ac4e2df.zip | |
mesalib pixman xkbcomp git update 13 jan 2011
| -rw-r--r-- | compare.bat | 1 | ||||
| -rw-r--r-- | mesalib/include/EGL/egl.h | 658 | ||||
| -rw-r--r-- | mesalib/src/glsl/Makefile | 2 | ||||
| -rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 18 | ||||
| -rw-r--r-- | mesalib/src/glsl/ir.cpp | 1 | ||||
| -rw-r--r-- | mesalib/src/glsl/ir.h | 9 | ||||
| -rw-r--r-- | mesalib/src/glsl/ir_print_visitor.cpp | 3 | ||||
| -rw-r--r-- | mesalib/src/glsl/ir_reader.cpp | 997 | ||||
| -rw-r--r-- | mesalib/src/glsl/lower_jumps.cpp | 2 | ||||
| -rw-r--r-- | mesalib/src/glsl/s_expression.cpp | 69 | ||||
| -rw-r--r-- | mesalib/src/glsl/s_expression.h | 39 | ||||
| -rw-r--r-- | mesalib/src/mesa/drivers/dri/common/dri_util.c | 3 | ||||
| -rw-r--r-- | mesalib/src/mesa/main/extensions.c | 908 | ||||
| -rw-r--r-- | mesalib/src/mesa/main/fbobject.c | 9 | ||||
| -rw-r--r-- | mesalib/src/mesa/main/get.c | 18 | ||||
| -rw-r--r-- | mesalib/src/mesa/main/mtypes.h | 3 | ||||
| -rw-r--r-- | mesalib/src/mesa/main/texenvprogram.c | 4 | ||||
| -rw-r--r-- | mesalib/src/mesa/main/texrender.c | 5 | ||||
| -rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_queryobj.c | 2 | ||||
| -rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_texture.c | 3 | ||||
| -rw-r--r-- | pixman/pixman/pixman-radial-gradient.c | 20 | ||||
| -rw-r--r-- | xkbcomp/configure.ac | 4 | 
22 files changed, 1356 insertions, 1422 deletions
| diff --git a/compare.bat b/compare.bat index 8d2b9a546..b11995978 100644 --- a/compare.bat +++ b/compare.bat @@ -11,3 +11,4 @@ fcg xkbcomp            ..\released\xkbcomp  fcg pixman             ..\released\pixman          
  fcg xextproto          ..\released\X11\extensions       
  fcg randrproto         ..\released\X11\extensions
 +fcg mesa               ..\released\mesalib      
\ No newline at end of file diff --git a/mesalib/include/EGL/egl.h b/mesalib/include/EGL/egl.h index 990ce0a45..fe33f2e23 100644 --- a/mesalib/include/EGL/egl.h +++ b/mesalib/include/EGL/egl.h @@ -1,329 +1,329 @@ -/* -*- mode: c; tab-width: 8; -*- */ -/* vi: set sw=4 ts=8: */ -/* Reference version of egl.h for EGL 1.4. - * $Revision$ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $ - */ - -/* -** Copyright (c) 2007-2009 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are 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 Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 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 -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#ifndef __egl_h_ -#define __egl_h_ - -/* All platform-dependent types and macro boilerplate (such as EGLAPI - * and EGLAPIENTRY) should go in eglplatform.h. - */ -#include <EGL/eglplatform.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* EGL Types */ -/* EGLint is defined in eglplatform.h */ -typedef unsigned int EGLBoolean; -typedef unsigned int EGLenum; -typedef void *EGLConfig; -typedef void *EGLContext; -typedef void *EGLDisplay; -typedef void *EGLSurface; -typedef void *EGLClientBuffer; - -/* EGL Versioning */ -#define EGL_VERSION_1_0			1 -#define EGL_VERSION_1_1			1 -#define EGL_VERSION_1_2			1 -#define EGL_VERSION_1_3			1 -#define EGL_VERSION_1_4			1 - -/* EGL Enumerants. Bitmasks and other exceptional cases aside, most - * enums are assigned unique values starting at 0x3000. - */ - -/* EGL aliases */ -#define EGL_FALSE			0 -#define EGL_TRUE			1 - -/* Out-of-band handle values */ -#define EGL_DEFAULT_DISPLAY		((EGLNativeDisplayType)0) -#define EGL_NO_CONTEXT			((EGLContext)0) -#define EGL_NO_DISPLAY			((EGLDisplay)0) -#define EGL_NO_SURFACE			((EGLSurface)0) - -/* Out-of-band attribute value */ -#define EGL_DONT_CARE			((EGLint)-1) - -/* Errors / GetError return values */ -#define EGL_SUCCESS			0x3000 -#define EGL_NOT_INITIALIZED		0x3001 -#define EGL_BAD_ACCESS			0x3002 -#define EGL_BAD_ALLOC			0x3003 -#define EGL_BAD_ATTRIBUTE		0x3004 -#define EGL_BAD_CONFIG			0x3005 -#define EGL_BAD_CONTEXT			0x3006 -#define EGL_BAD_CURRENT_SURFACE		0x3007 -#define EGL_BAD_DISPLAY			0x3008 -#define EGL_BAD_MATCH			0x3009 -#define EGL_BAD_NATIVE_PIXMAP		0x300A -#define EGL_BAD_NATIVE_WINDOW		0x300B -#define EGL_BAD_PARAMETER		0x300C -#define EGL_BAD_SURFACE			0x300D -#define EGL_CONTEXT_LOST		0x300E	/* EGL 1.1 - IMG_power_management */ - -/* Reserved 0x300F-0x301F for additional errors */ - -/* Config attributes */ -#define EGL_BUFFER_SIZE			0x3020 -#define EGL_ALPHA_SIZE			0x3021 -#define EGL_BLUE_SIZE			0x3022 -#define EGL_GREEN_SIZE			0x3023 -#define EGL_RED_SIZE			0x3024 -#define EGL_DEPTH_SIZE			0x3025 -#define EGL_STENCIL_SIZE		0x3026 -#define EGL_CONFIG_CAVEAT		0x3027 -#define EGL_CONFIG_ID			0x3028 -#define EGL_LEVEL			0x3029 -#define EGL_MAX_PBUFFER_HEIGHT		0x302A -#define EGL_MAX_PBUFFER_PIXELS		0x302B -#define EGL_MAX_PBUFFER_WIDTH		0x302C -#define EGL_NATIVE_RENDERABLE		0x302D -#define EGL_NATIVE_VISUAL_ID		0x302E -#define EGL_NATIVE_VISUAL_TYPE		0x302F -#define EGL_SAMPLES			0x3031 -#define EGL_SAMPLE_BUFFERS		0x3032 -#define EGL_SURFACE_TYPE		0x3033 -#define EGL_TRANSPARENT_TYPE		0x3034 -#define EGL_TRANSPARENT_BLUE_VALUE	0x3035 -#define EGL_TRANSPARENT_GREEN_VALUE	0x3036 -#define EGL_TRANSPARENT_RED_VALUE	0x3037 -#define EGL_NONE			0x3038	/* Attrib list terminator */ -#define EGL_BIND_TO_TEXTURE_RGB		0x3039 -#define EGL_BIND_TO_TEXTURE_RGBA	0x303A -#define EGL_MIN_SWAP_INTERVAL		0x303B -#define EGL_MAX_SWAP_INTERVAL		0x303C -#define EGL_LUMINANCE_SIZE		0x303D -#define EGL_ALPHA_MASK_SIZE		0x303E -#define EGL_COLOR_BUFFER_TYPE		0x303F -#define EGL_RENDERABLE_TYPE		0x3040 -#define EGL_MATCH_NATIVE_PIXMAP		0x3041	/* Pseudo-attribute (not queryable) */ -#define EGL_CONFORMANT			0x3042 - -/* Reserved 0x3041-0x304F for additional config attributes */ - -/* Config attribute values */ -#define EGL_SLOW_CONFIG			0x3050	/* EGL_CONFIG_CAVEAT value */ -#define EGL_NON_CONFORMANT_CONFIG	0x3051	/* EGL_CONFIG_CAVEAT value */ -#define EGL_TRANSPARENT_RGB		0x3052	/* EGL_TRANSPARENT_TYPE value */ -#define EGL_RGB_BUFFER			0x308E	/* EGL_COLOR_BUFFER_TYPE value */ -#define EGL_LUMINANCE_BUFFER		0x308F	/* EGL_COLOR_BUFFER_TYPE value */ - -/* More config attribute values, for EGL_TEXTURE_FORMAT */ -#define EGL_NO_TEXTURE			0x305C -#define EGL_TEXTURE_RGB			0x305D -#define EGL_TEXTURE_RGBA		0x305E -#define EGL_TEXTURE_2D			0x305F - -/* Config attribute mask bits */ -#define EGL_PBUFFER_BIT			0x0001	/* EGL_SURFACE_TYPE mask bits */ -#define EGL_PIXMAP_BIT			0x0002	/* EGL_SURFACE_TYPE mask bits */ -#define EGL_WINDOW_BIT			0x0004	/* EGL_SURFACE_TYPE mask bits */ -#define EGL_VG_COLORSPACE_LINEAR_BIT	0x0020	/* EGL_SURFACE_TYPE mask bits */ -#define EGL_VG_ALPHA_FORMAT_PRE_BIT	0x0040	/* EGL_SURFACE_TYPE mask bits */ -#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200	/* EGL_SURFACE_TYPE mask bits */ -#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400	/* EGL_SURFACE_TYPE mask bits */ - -#define EGL_OPENGL_ES_BIT		0x0001	/* EGL_RENDERABLE_TYPE mask bits */ -#define EGL_OPENVG_BIT			0x0002	/* EGL_RENDERABLE_TYPE mask bits */ -#define EGL_OPENGL_ES2_BIT		0x0004	/* EGL_RENDERABLE_TYPE mask bits */ -#define EGL_OPENGL_BIT			0x0008	/* EGL_RENDERABLE_TYPE mask bits */ - -/* QueryString targets */ -#define EGL_VENDOR			0x3053 -#define EGL_VERSION			0x3054 -#define EGL_EXTENSIONS			0x3055 -#define EGL_CLIENT_APIS			0x308D - -/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */ -#define EGL_HEIGHT			0x3056 -#define EGL_WIDTH			0x3057 -#define EGL_LARGEST_PBUFFER		0x3058 -#define EGL_TEXTURE_FORMAT		0x3080 -#define EGL_TEXTURE_TARGET		0x3081 -#define EGL_MIPMAP_TEXTURE		0x3082 -#define EGL_MIPMAP_LEVEL		0x3083 -#define EGL_RENDER_BUFFER		0x3086 -#define EGL_VG_COLORSPACE		0x3087 -#define EGL_VG_ALPHA_FORMAT		0x3088 -#define EGL_HORIZONTAL_RESOLUTION	0x3090 -#define EGL_VERTICAL_RESOLUTION		0x3091 -#define EGL_PIXEL_ASPECT_RATIO		0x3092 -#define EGL_SWAP_BEHAVIOR		0x3093 -#define EGL_MULTISAMPLE_RESOLVE		0x3099 - -/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */ -#define EGL_BACK_BUFFER			0x3084 -#define EGL_SINGLE_BUFFER		0x3085 - -/* OpenVG color spaces */ -#define EGL_VG_COLORSPACE_sRGB		0x3089	/* EGL_VG_COLORSPACE value */ -#define EGL_VG_COLORSPACE_LINEAR	0x308A	/* EGL_VG_COLORSPACE value */ - -/* OpenVG alpha formats */ -#define EGL_VG_ALPHA_FORMAT_NONPRE	0x308B	/* EGL_ALPHA_FORMAT value */ -#define EGL_VG_ALPHA_FORMAT_PRE		0x308C	/* EGL_ALPHA_FORMAT value */ - -/* Constant scale factor by which fractional display resolutions & - * aspect ratio are scaled when queried as integer values. - */ -#define EGL_DISPLAY_SCALING		10000 - -/* Unknown display resolution/aspect ratio */ -#define EGL_UNKNOWN			((EGLint)-1) - -/* Back buffer swap behaviors */ -#define EGL_BUFFER_PRESERVED		0x3094	/* EGL_SWAP_BEHAVIOR value */ -#define EGL_BUFFER_DESTROYED		0x3095	/* EGL_SWAP_BEHAVIOR value */ - -/* CreatePbufferFromClientBuffer buffer types */ -#define EGL_OPENVG_IMAGE		0x3096 - -/* QueryContext targets */ -#define EGL_CONTEXT_CLIENT_TYPE		0x3097 - -/* CreateContext attributes */ -#define EGL_CONTEXT_CLIENT_VERSION	0x3098 - -/* Multisample resolution behaviors */ -#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A	/* EGL_MULTISAMPLE_RESOLVE value */ -#define EGL_MULTISAMPLE_RESOLVE_BOX	0x309B	/* EGL_MULTISAMPLE_RESOLVE value */ - -/* BindAPI/QueryAPI targets */ -#define EGL_OPENGL_ES_API		0x30A0 -#define EGL_OPENVG_API			0x30A1 -#define EGL_OPENGL_API			0x30A2 - -/* GetCurrentSurface targets */ -#define EGL_DRAW			0x3059 -#define EGL_READ			0x305A - -/* WaitNative engines */ -#define EGL_CORE_NATIVE_ENGINE		0x305B - -/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */ -#define EGL_COLORSPACE			EGL_VG_COLORSPACE -#define EGL_ALPHA_FORMAT		EGL_VG_ALPHA_FORMAT -#define EGL_COLORSPACE_sRGB		EGL_VG_COLORSPACE_sRGB -#define EGL_COLORSPACE_LINEAR		EGL_VG_COLORSPACE_LINEAR -#define EGL_ALPHA_FORMAT_NONPRE		EGL_VG_ALPHA_FORMAT_NONPRE -#define EGL_ALPHA_FORMAT_PRE		EGL_VG_ALPHA_FORMAT_PRE - -/* EGL extensions must request enum blocks from the Khronos - * API Registrar, who maintains the enumerant registry. Submit - * a bug in Khronos Bugzilla against task "Registry". - */ - - - -/* EGL Functions */ - -EGLAPI EGLint EGLAPIENTRY eglGetError(void); - -EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id); -EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor); -EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy); - -EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name); - -EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, -			 EGLint config_size, EGLint *num_config); -EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, -			   EGLConfig *configs, EGLint config_size, -			   EGLint *num_config); -EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, -			      EGLint attribute, EGLint *value); - -EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, -				  EGLNativeWindowType win, -				  const EGLint *attrib_list); -EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, -				   const EGLint *attrib_list); -EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, -				  EGLNativePixmapType pixmap, -				  const EGLint *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface); -EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, -			   EGLint attribute, EGLint *value); - -EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api); -EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void); - -EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void); - -EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void); - -EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer( -	      EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, -	      EGLConfig config, const EGLint *attrib_list); - -EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, -			    EGLint attribute, EGLint value); -EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); -EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer); - - -EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval); - - -EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, -			    EGLContext share_context, -			    const EGLint *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx); -EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, -			  EGLSurface read, EGLContext ctx); - -EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void); -EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw); -EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void); -EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, -			   EGLint attribute, EGLint *value); - -EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void); -EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine); -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface); -EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, -			  EGLNativePixmapType target); - -/* This is a generic function pointer type, whose name indicates it must - * be cast to the proper type *and calling convention* before use. - */ -typedef void (*__eglMustCastToProperFunctionPointerType)(void); - -/* Now, define eglGetProcAddress using the generic function ptr. type */ -EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY -       eglGetProcAddress(const char *procname); - -#ifdef __cplusplus -} -#endif - -#endif /* __egl_h_ */ +/* -*- mode: c; tab-width: 8; -*- */
 +/* vi: set sw=4 ts=8: */
 +/* Reference version of egl.h for EGL 1.4.
 + * $Revision$ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
 + */
 +
 +/*
 +** Copyright (c) 2007-2009 The Khronos Group Inc.
 +**
 +** Permission is hereby granted, free of charge, to any person obtaining a
 +** copy of this software and/or associated documentation files (the
 +** "Materials"), to deal in the Materials without restriction, including
 +** without limitation the rights to use, copy, modify, merge, publish,
 +** distribute, sublicense, and/or sell copies of the Materials, and to
 +** permit persons to whom the Materials are 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 Materials.
 +**
 +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 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
 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 +*/
 +
 +#ifndef __egl_h_
 +#define __egl_h_
 +
 +/* All platform-dependent types and macro boilerplate (such as EGLAPI
 + * and EGLAPIENTRY) should go in eglplatform.h.
 + */
 +#include <EGL/eglplatform.h>
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif
 +
 +/* EGL Types */
 +/* EGLint is defined in eglplatform.h */
 +typedef unsigned int EGLBoolean;
 +typedef unsigned int EGLenum;
 +typedef void *EGLConfig;
 +typedef void *EGLContext;
 +typedef void *EGLDisplay;
 +typedef void *EGLSurface;
 +typedef void *EGLClientBuffer;
 +
 +/* EGL Versioning */
 +#define EGL_VERSION_1_0			1
 +#define EGL_VERSION_1_1			1
 +#define EGL_VERSION_1_2			1
 +#define EGL_VERSION_1_3			1
 +#define EGL_VERSION_1_4			1
 +
 +/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
 + * enums are assigned unique values starting at 0x3000.
 + */
 +
 +/* EGL aliases */
 +#define EGL_FALSE			0
 +#define EGL_TRUE			1
 +
 +/* Out-of-band handle values */
 +#define EGL_DEFAULT_DISPLAY		((EGLNativeDisplayType)0)
 +#define EGL_NO_CONTEXT			((EGLContext)0)
 +#define EGL_NO_DISPLAY			((EGLDisplay)0)
 +#define EGL_NO_SURFACE			((EGLSurface)0)
 +
 +/* Out-of-band attribute value */
 +#define EGL_DONT_CARE			((EGLint)-1)
 +
 +/* Errors / GetError return values */
 +#define EGL_SUCCESS			0x3000
 +#define EGL_NOT_INITIALIZED		0x3001
 +#define EGL_BAD_ACCESS			0x3002
 +#define EGL_BAD_ALLOC			0x3003
 +#define EGL_BAD_ATTRIBUTE		0x3004
 +#define EGL_BAD_CONFIG			0x3005
 +#define EGL_BAD_CONTEXT			0x3006
 +#define EGL_BAD_CURRENT_SURFACE		0x3007
 +#define EGL_BAD_DISPLAY			0x3008
 +#define EGL_BAD_MATCH			0x3009
 +#define EGL_BAD_NATIVE_PIXMAP		0x300A
 +#define EGL_BAD_NATIVE_WINDOW		0x300B
 +#define EGL_BAD_PARAMETER		0x300C
 +#define EGL_BAD_SURFACE			0x300D
 +#define EGL_CONTEXT_LOST		0x300E	/* EGL 1.1 - IMG_power_management */
 +
 +/* Reserved 0x300F-0x301F for additional errors */
 +
 +/* Config attributes */
 +#define EGL_BUFFER_SIZE			0x3020
 +#define EGL_ALPHA_SIZE			0x3021
 +#define EGL_BLUE_SIZE			0x3022
 +#define EGL_GREEN_SIZE			0x3023
 +#define EGL_RED_SIZE			0x3024
 +#define EGL_DEPTH_SIZE			0x3025
 +#define EGL_STENCIL_SIZE		0x3026
 +#define EGL_CONFIG_CAVEAT		0x3027
 +#define EGL_CONFIG_ID			0x3028
 +#define EGL_LEVEL			0x3029
 +#define EGL_MAX_PBUFFER_HEIGHT		0x302A
 +#define EGL_MAX_PBUFFER_PIXELS		0x302B
 +#define EGL_MAX_PBUFFER_WIDTH		0x302C
 +#define EGL_NATIVE_RENDERABLE		0x302D
 +#define EGL_NATIVE_VISUAL_ID		0x302E
 +#define EGL_NATIVE_VISUAL_TYPE		0x302F
 +#define EGL_SAMPLES			0x3031
 +#define EGL_SAMPLE_BUFFERS		0x3032
 +#define EGL_SURFACE_TYPE		0x3033
 +#define EGL_TRANSPARENT_TYPE		0x3034
 +#define EGL_TRANSPARENT_BLUE_VALUE	0x3035
 +#define EGL_TRANSPARENT_GREEN_VALUE	0x3036
 +#define EGL_TRANSPARENT_RED_VALUE	0x3037
 +#define EGL_NONE			0x3038	/* Attrib list terminator */
 +#define EGL_BIND_TO_TEXTURE_RGB		0x3039
 +#define EGL_BIND_TO_TEXTURE_RGBA	0x303A
 +#define EGL_MIN_SWAP_INTERVAL		0x303B
 +#define EGL_MAX_SWAP_INTERVAL		0x303C
 +#define EGL_LUMINANCE_SIZE		0x303D
 +#define EGL_ALPHA_MASK_SIZE		0x303E
 +#define EGL_COLOR_BUFFER_TYPE		0x303F
 +#define EGL_RENDERABLE_TYPE		0x3040
 +#define EGL_MATCH_NATIVE_PIXMAP		0x3041	/* Pseudo-attribute (not queryable) */
 +#define EGL_CONFORMANT			0x3042
 +
 +/* Reserved 0x3041-0x304F for additional config attributes */
 +
 +/* Config attribute values */
 +#define EGL_SLOW_CONFIG			0x3050	/* EGL_CONFIG_CAVEAT value */
 +#define EGL_NON_CONFORMANT_CONFIG	0x3051	/* EGL_CONFIG_CAVEAT value */
 +#define EGL_TRANSPARENT_RGB		0x3052	/* EGL_TRANSPARENT_TYPE value */
 +#define EGL_RGB_BUFFER			0x308E	/* EGL_COLOR_BUFFER_TYPE value */
 +#define EGL_LUMINANCE_BUFFER		0x308F	/* EGL_COLOR_BUFFER_TYPE value */
 +
 +/* More config attribute values, for EGL_TEXTURE_FORMAT */
 +#define EGL_NO_TEXTURE			0x305C
 +#define EGL_TEXTURE_RGB			0x305D
 +#define EGL_TEXTURE_RGBA		0x305E
 +#define EGL_TEXTURE_2D			0x305F
 +
 +/* Config attribute mask bits */
 +#define EGL_PBUFFER_BIT			0x0001	/* EGL_SURFACE_TYPE mask bits */
 +#define EGL_PIXMAP_BIT			0x0002	/* EGL_SURFACE_TYPE mask bits */
 +#define EGL_WINDOW_BIT			0x0004	/* EGL_SURFACE_TYPE mask bits */
 +#define EGL_VG_COLORSPACE_LINEAR_BIT	0x0020	/* EGL_SURFACE_TYPE mask bits */
 +#define EGL_VG_ALPHA_FORMAT_PRE_BIT	0x0040	/* EGL_SURFACE_TYPE mask bits */
 +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200	/* EGL_SURFACE_TYPE mask bits */
 +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400	/* EGL_SURFACE_TYPE mask bits */
 +
 +#define EGL_OPENGL_ES_BIT		0x0001	/* EGL_RENDERABLE_TYPE mask bits */
 +#define EGL_OPENVG_BIT			0x0002	/* EGL_RENDERABLE_TYPE mask bits */
 +#define EGL_OPENGL_ES2_BIT		0x0004	/* EGL_RENDERABLE_TYPE mask bits */
 +#define EGL_OPENGL_BIT			0x0008	/* EGL_RENDERABLE_TYPE mask bits */
 +
 +/* QueryString targets */
 +#define EGL_VENDOR			0x3053
 +#define EGL_VERSION			0x3054
 +#define EGL_EXTENSIONS			0x3055
 +#define EGL_CLIENT_APIS			0x308D
 +
 +/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
 +#define EGL_HEIGHT			0x3056
 +#define EGL_WIDTH			0x3057
 +#define EGL_LARGEST_PBUFFER		0x3058
 +#define EGL_TEXTURE_FORMAT		0x3080
 +#define EGL_TEXTURE_TARGET		0x3081
 +#define EGL_MIPMAP_TEXTURE		0x3082
 +#define EGL_MIPMAP_LEVEL		0x3083
 +#define EGL_RENDER_BUFFER		0x3086
 +#define EGL_VG_COLORSPACE		0x3087
 +#define EGL_VG_ALPHA_FORMAT		0x3088
 +#define EGL_HORIZONTAL_RESOLUTION	0x3090
 +#define EGL_VERTICAL_RESOLUTION		0x3091
 +#define EGL_PIXEL_ASPECT_RATIO		0x3092
 +#define EGL_SWAP_BEHAVIOR		0x3093
 +#define EGL_MULTISAMPLE_RESOLVE		0x3099
 +
 +/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
 +#define EGL_BACK_BUFFER			0x3084
 +#define EGL_SINGLE_BUFFER		0x3085
 +
 +/* OpenVG color spaces */
 +#define EGL_VG_COLORSPACE_sRGB		0x3089	/* EGL_VG_COLORSPACE value */
 +#define EGL_VG_COLORSPACE_LINEAR	0x308A	/* EGL_VG_COLORSPACE value */
 +
 +/* OpenVG alpha formats */
 +#define EGL_VG_ALPHA_FORMAT_NONPRE	0x308B	/* EGL_ALPHA_FORMAT value */
 +#define EGL_VG_ALPHA_FORMAT_PRE		0x308C	/* EGL_ALPHA_FORMAT value */
 +
 +/* Constant scale factor by which fractional display resolutions &
 + * aspect ratio are scaled when queried as integer values.
 + */
 +#define EGL_DISPLAY_SCALING		10000
 +
 +/* Unknown display resolution/aspect ratio */
 +#define EGL_UNKNOWN			((EGLint)-1)
 +
 +/* Back buffer swap behaviors */
 +#define EGL_BUFFER_PRESERVED		0x3094	/* EGL_SWAP_BEHAVIOR value */
 +#define EGL_BUFFER_DESTROYED		0x3095	/* EGL_SWAP_BEHAVIOR value */
 +
 +/* CreatePbufferFromClientBuffer buffer types */
 +#define EGL_OPENVG_IMAGE		0x3096
 +
 +/* QueryContext targets */
 +#define EGL_CONTEXT_CLIENT_TYPE		0x3097
 +
 +/* CreateContext attributes */
 +#define EGL_CONTEXT_CLIENT_VERSION	0x3098
 +
 +/* Multisample resolution behaviors */
 +#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A	/* EGL_MULTISAMPLE_RESOLVE value */
 +#define EGL_MULTISAMPLE_RESOLVE_BOX	0x309B	/* EGL_MULTISAMPLE_RESOLVE value */
 +
 +/* BindAPI/QueryAPI targets */
 +#define EGL_OPENGL_ES_API		0x30A0
 +#define EGL_OPENVG_API			0x30A1
 +#define EGL_OPENGL_API			0x30A2
 +
 +/* GetCurrentSurface targets */
 +#define EGL_DRAW			0x3059
 +#define EGL_READ			0x305A
 +
 +/* WaitNative engines */
 +#define EGL_CORE_NATIVE_ENGINE		0x305B
 +
 +/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
 +#define EGL_COLORSPACE			EGL_VG_COLORSPACE
 +#define EGL_ALPHA_FORMAT		EGL_VG_ALPHA_FORMAT
 +#define EGL_COLORSPACE_sRGB		EGL_VG_COLORSPACE_sRGB
 +#define EGL_COLORSPACE_LINEAR		EGL_VG_COLORSPACE_LINEAR
 +#define EGL_ALPHA_FORMAT_NONPRE		EGL_VG_ALPHA_FORMAT_NONPRE
 +#define EGL_ALPHA_FORMAT_PRE		EGL_VG_ALPHA_FORMAT_PRE
 +
 +/* EGL extensions must request enum blocks from the Khronos
 + * API Registrar, who maintains the enumerant registry. Submit
 + * a bug in Khronos Bugzilla against task "Registry".
 + */
 +
 +
 +
 +/* EGL Functions */
 +
 +EGLAPI EGLint EGLAPIENTRY eglGetError(void);
 +
 +EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
 +EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
 +EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
 +
 +EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
 +
 +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
 +			 EGLint config_size, EGLint *num_config);
 +EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
 +			   EGLConfig *configs, EGLint config_size,
 +			   EGLint *num_config);
 +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
 +			      EGLint attribute, EGLint *value);
 +
 +EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
 +				  EGLNativeWindowType win,
 +				  const EGLint *attrib_list);
 +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
 +				   const EGLint *attrib_list);
 +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
 +				  EGLNativePixmapType pixmap,
 +				  const EGLint *attrib_list);
 +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
 +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
 +			   EGLint attribute, EGLint *value);
 +
 +EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
 +EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
 +
 +EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
 +
 +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
 +
 +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
 +	      EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
 +	      EGLConfig config, const EGLint *attrib_list);
 +
 +EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
 +			    EGLint attribute, EGLint value);
 +EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
 +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
 +
 +
 +EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
 +
 +
 +EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
 +			    EGLContext share_context,
 +			    const EGLint *attrib_list);
 +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
 +EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
 +			  EGLSurface read, EGLContext ctx);
 +
 +EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
 +EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
 +EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
 +EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
 +			   EGLint attribute, EGLint *value);
 +
 +EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
 +EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
 +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
 +EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
 +			  EGLNativePixmapType target);
 +
 +/* This is a generic function pointer type, whose name indicates it must
 + * be cast to the proper type *and calling convention* before use.
 + */
 +typedef void (*__eglMustCastToProperFunctionPointerType)(void);
 +
 +/* Now, define eglGetProcAddress using the generic function ptr. type */
 +EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
 +       eglGetProcAddress(const char *procname);
 +
 +#ifdef __cplusplus
 +}
 +#endif
 +
 +#endif /* __egl_h_ */
 diff --git a/mesalib/src/glsl/Makefile b/mesalib/src/glsl/Makefile index f522aa577..22e01415f 100644 --- a/mesalib/src/glsl/Makefile +++ b/mesalib/src/glsl/Makefile @@ -174,7 +174,7 @@ glcpp/glcpp-parse.c: glcpp/glcpp-parse.y  	bison -v -o "$@" --defines=glcpp/glcpp-parse.h $<
  builtin_compiler: $(GLSL2_OBJECTS) $(OBJECTS) builtin_stubs.o
 -	$(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(TALLOC_LIBS) $(OBJECTS) $(GLSL2_OBJECTS) builtin_stubs.o -o builtin_compiler
 +	$(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $(GLSL2_OBJECTS) builtin_stubs.o $(TALLOC_LIBS) -o $@
  builtin_function.cpp: builtins/profiles/* builtins/ir/* builtins/tools/generate_builtins.py builtins/tools/texture_builtins.py builtin_compiler
  	@echo Regenerating builtin_function.cpp...
 diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 74a3d4775..ef209d078 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -1623,6 +1623,7 @@ ast_expression::hir(exec_list *instructions,        result = new(ctx) ir_dereference_variable(var);
        if (var != NULL) {
 +	 var->used = true;
  	 type = result->type;
        } else {
  	 _mesa_glsl_error(& loc, state, "`%s' undeclared",
 @@ -1797,8 +1798,16 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,  				 struct _mesa_glsl_parse_state *state,
  				 YYLTYPE *loc)
  {
 -   if (qual->flags.q.invariant)
 -      var->invariant = 1;
 +   if (qual->flags.q.invariant) {
 +      if (var->used) {
 +	 _mesa_glsl_error(loc, state,
 +			  "variable `%s' may not be redeclared "
 +			  "`invariant' after being used",
 +			  var->name);
 +      } else {
 +	 var->invariant = 1;
 +      }
 +   }
     /* FINISHME: Mark 'in' variables at global scope as read-only. */
     if (qual->flags.q.constant || qual->flags.q.attribute
 @@ -2005,6 +2014,11 @@ ast_declarator_list::hir(exec_list *instructions,  	    _mesa_glsl_error(& loc, state,
  			     "`%s' cannot be marked invariant, fragment shader "
  			     "inputs only\n", decl->identifier);
 +	 } else if (earlier->used) {
 +	    _mesa_glsl_error(& loc, state,
 +			     "variable `%s' may not be redeclared "
 +			     "`invariant' after being used",
 +			     earlier->name);
  	 } else {
  	    earlier->invariant = true;
  	 }
 diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index dfab1f1af..28fe3f4ac 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -1325,6 +1325,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,     this->constant_value = NULL;
     this->origin_upper_left = false;
     this->pixel_center_integer = false;
 +   this->used = false;
     if (type && type->base_type == GLSL_TYPE_SAMPLER)
        this->read_only = true;
 diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index d11047f1d..f3a565f2e 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -295,6 +295,15 @@ public:     unsigned invariant:1;
     /**
 +    * Has this variable been used for reading or writing?
 +    *
 +    * Several GLSL semantic checks require knowledge of whether or not a
 +    * variable has been used.  For example, it is an error to redeclare a
 +    * variable as invariant after it has been used.
 +    */
 +   unsigned used:1;
 +
 +   /**
      * Storage class of the variable.
      *
      * \sa ir_variable_mode
 diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index bed838fe8..3609c0e12 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -281,9 +281,6 @@ void ir_print_visitor::visit(ir_assignment *ir)     if (ir->condition)
        ir->condition->accept(this);
 -   else
 -      printf("(constant bool (1))");
 -
     char mask[5];
     unsigned j = 0;
 diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp index b15df6ddf..67e3847e4 100644 --- a/mesalib/src/glsl/ir_reader.cpp +++ b/mesalib/src/glsl/ir_reader.cpp @@ -21,8 +21,6 @@   * DEALINGS IN THE SOFTWARE.
   */
 -#include <cstdarg>
 -
  extern "C" {
  #include <talloc.h>
  }
 @@ -34,69 +32,78 @@ extern "C" {  const static bool debug = false;
 -static void ir_read_error(_mesa_glsl_parse_state *, s_expression *,
 -			  const char *fmt, ...);
 -static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
 -
 -static void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *,
 -			        s_expression *);
 -static ir_function *read_function(_mesa_glsl_parse_state *, s_list *,
 -				  bool skip_body);
 -static void read_function_sig(_mesa_glsl_parse_state *, ir_function *,
 -			      s_list *, bool skip_body);
 -
 -static void read_instructions(_mesa_glsl_parse_state *, exec_list *,
 -			      s_expression *, ir_loop *);
 -static ir_instruction *read_instruction(_mesa_glsl_parse_state *,
 -				        s_expression *, ir_loop *);
 -static ir_variable *read_declaration(_mesa_glsl_parse_state *, s_list *);
 -static ir_if *read_if(_mesa_glsl_parse_state *, s_list *, ir_loop *);
 -static ir_loop *read_loop(_mesa_glsl_parse_state *st, s_list *list);
 -static ir_return *read_return(_mesa_glsl_parse_state *, s_list *);
 -
 -static ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *);
 -static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_list *);
 -static ir_expression *read_expression(_mesa_glsl_parse_state *, s_list *);
 -static ir_call *read_call(_mesa_glsl_parse_state *, s_list *);
 -static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_list *);
 -static ir_constant *read_constant(_mesa_glsl_parse_state *, s_list *);
 -static ir_texture *read_texture(_mesa_glsl_parse_state *, s_list *);
 -
 -static ir_dereference *read_dereference(_mesa_glsl_parse_state *,
 -				        s_expression *);
 -static ir_dereference_variable *
 -read_var_ref(_mesa_glsl_parse_state *, s_list *);
 -static ir_dereference_array *
 -read_array_ref(_mesa_glsl_parse_state *, s_list *);
 -static ir_dereference_record *
 -read_record_ref(_mesa_glsl_parse_state *, s_list *);
 +class ir_reader {
 +public:
 +   ir_reader(_mesa_glsl_parse_state *);
 +
 +   void read(exec_list *instructions, const char *src, bool scan_for_protos);
 +
 +private:
 +   void *mem_ctx;
 +   _mesa_glsl_parse_state *state;
 +
 +   void ir_read_error(s_expression *, const char *fmt, ...);
 +
 +   const glsl_type *read_type(s_expression *);
 +
 +   void scan_for_prototypes(exec_list *, s_expression *);
 +   ir_function *read_function(s_expression *, bool skip_body);
 +   void read_function_sig(ir_function *, s_expression *, bool skip_body);
 +
 +   void read_instructions(exec_list *, s_expression *, ir_loop *);
 +   ir_instruction *read_instruction(s_expression *, ir_loop *);
 +   ir_variable *read_declaration(s_expression *);
 +   ir_if *read_if(s_expression *, ir_loop *);
 +   ir_loop *read_loop(s_expression *);
 +   ir_return *read_return(s_expression *);
 +   ir_rvalue *read_rvalue(s_expression *);
 +   ir_assignment *read_assignment(s_expression *);
 +   ir_expression *read_expression(s_expression *);
 +   ir_call *read_call(s_expression *);
 +   ir_swizzle *read_swizzle(s_expression *);
 +   ir_constant *read_constant(s_expression *);
 +   ir_texture *read_texture(s_expression *);
 +
 +   ir_dereference *read_dereference(s_expression *);
 +};
 +
 +ir_reader::ir_reader(_mesa_glsl_parse_state *state) : state(state)
 +{
 +   this->mem_ctx = state;
 +}
  void
  _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
  		   const char *src, bool scan_for_protos)
  {
 -   s_expression *expr = s_expression::read_expression(state, src);
 +   ir_reader r(state);
 +   r.read(instructions, src, scan_for_protos);
 +}
 +
 +void
 +ir_reader::read(exec_list *instructions, const char *src, bool scan_for_protos)
 +{
 +   s_expression *expr = s_expression::read_expression(mem_ctx, src);
     if (expr == NULL) {
 -      ir_read_error(state, NULL, "couldn't parse S-Expression.");
 +      ir_read_error(NULL, "couldn't parse S-Expression.");
        return;
     }
     if (scan_for_protos) {
 -      scan_for_prototypes(state, instructions, expr);
 +      scan_for_prototypes(instructions, expr);
        if (state->error)
  	 return;
     }
 -   read_instructions(state, instructions, expr, NULL);
 +   read_instructions(instructions, expr, NULL);
     talloc_free(expr);
     if (debug)
        validate_ir_tree(instructions);
  }
 -static void
 -ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr,
 -	      const char *fmt, ...)
 +void
 +ir_reader::ir_read_error(s_expression *expr, const char *fmt, ...)
  {
     va_list ap;
 @@ -121,68 +128,43 @@ ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr,     }
  }
 -static const glsl_type *
 -read_type(_mesa_glsl_parse_state *st, s_expression *expr)
 +const glsl_type *
 +ir_reader::read_type(s_expression *expr)
  {
 -   s_list *list = SX_AS_LIST(expr);
 -   if (list != NULL) {
 -      s_symbol *type_sym = SX_AS_SYMBOL(list->subexpressions.get_head());
 -      if (type_sym == NULL) {
 -	 ir_read_error(st, expr, "expected type (array ...) or (struct ...)");
 +   s_expression *s_base_type;
 +   s_int *s_size;
 +
 +   s_pattern pat[] = { "array", s_base_type, s_size };
 +   if (MATCH(expr, pat)) {
 +      const glsl_type *base_type = read_type(s_base_type);
 +      if (base_type == NULL) {
 +	 ir_read_error(NULL, "when reading base type of array type");
  	 return NULL;
        }
 -      if (strcmp(type_sym->value(), "array") == 0) {
 -	 if (list->length() != 3) {
 -	    ir_read_error(st, expr, "expected type (array <type> <int>)");
 -	    return NULL;
 -	 }
 -	 // Read base type
 -	 s_expression *base_expr = (s_expression*) type_sym->next;
 -	 const glsl_type *base_type = read_type(st, base_expr);
 -	 if (base_type == NULL) {
 -	    ir_read_error(st, NULL, "when reading base type of array");
 -	    return NULL;
 -	 }
 -
 -	 // Read array size
 -	 s_int *size = SX_AS_INT(base_expr->next);
 -	 if (size == NULL) {
 -	    ir_read_error(st, expr, "found non-integer array size");
 -	    return NULL;
 -	 }
 -
 -	 return glsl_type::get_array_instance(base_type, size->value());
 -      } else if (strcmp(type_sym->value(), "struct") == 0) {
 -	 assert(false); // FINISHME
 -      } else {
 -	 ir_read_error(st, expr, "expected (array ...) or (struct ...); "
 -				 "found (%s ...)", type_sym->value());
 -	 return NULL;
 -      }
 +      return glsl_type::get_array_instance(base_type, s_size->value());
     }
     s_symbol *type_sym = SX_AS_SYMBOL(expr);
     if (type_sym == NULL) {
 -      ir_read_error(st, expr, "expected <type> (symbol or list)");
 +      ir_read_error(expr, "expected <type>");
        return NULL;
     }
 -   const glsl_type *type = st->symbols->get_type(type_sym->value());
 +   const glsl_type *type = state->symbols->get_type(type_sym->value());
     if (type == NULL)
 -      ir_read_error(st, expr, "invalid type: %s", type_sym->value());
 +      ir_read_error(expr, "invalid type: %s", type_sym->value());
     return type;
  }
 -static void
 -scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
 -		    s_expression *expr)
 +void
 +ir_reader::scan_for_prototypes(exec_list *instructions, s_expression *expr)
  {
     s_list *list = SX_AS_LIST(expr);
     if (list == NULL) {
 -      ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
 +      ir_read_error(expr, "Expected (<instruction> ...); found an atom.");
        return;
     }
 @@ -195,94 +177,73 @@ scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,        if (tag == NULL || strcmp(tag->value(), "function") != 0)
  	 continue; // not a (function ...); ignore it.
 -      ir_function *f = read_function(st, sub, true);
 +      ir_function *f = read_function(sub, true);
        if (f == NULL)
  	 return;
        instructions->push_tail(f);
     }
  }
 -static ir_function *
 -read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
 +ir_function *
 +ir_reader::read_function(s_expression *expr, bool skip_body)
  {
 -   void *ctx = st;
     bool added = false;
 -   if (list->length() < 3) {
 -      ir_read_error(st, list, "Expected (function <name> (signature ...) ...)");
 -      return NULL;
 -   }
 +   s_symbol *name;
 -   s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
 -   if (name == NULL) {
 -      ir_read_error(st, list, "Expected (function <name> ...)");
 +   s_pattern pat[] = { "function", name };
 +   if (!PARTIAL_MATCH(expr, pat)) {
 +      ir_read_error(expr, "Expected (function <name> (signature ...) ...)");
        return NULL;
     }
 -   ir_function *f = st->symbols->get_function(name->value());
 +   ir_function *f = state->symbols->get_function(name->value());
     if (f == NULL) {
 -      f = new(ctx) ir_function(name->value());
 -      added = st->symbols->add_function(f);
 +      f = new(mem_ctx) ir_function(name->value());
 +      added = state->symbols->add_function(f);
        assert(added);
     }
 -   exec_list_iterator it = list->subexpressions.iterator();
 +   exec_list_iterator it = ((s_list *) expr)->subexpressions.iterator();
     it.next(); // skip "function" tag
     it.next(); // skip function name
     for (/* nothing */; it.has_next(); it.next()) {
 -      s_list *siglist = SX_AS_LIST(it.get());
 -      if (siglist == NULL) {
 -	 ir_read_error(st, list, "Expected (function (signature ...) ...)");
 -	 return NULL;
 -      }
 -
 -      s_symbol *tag = SX_AS_SYMBOL(siglist->subexpressions.get_head());
 -      if (tag == NULL || strcmp(tag->value(), "signature") != 0) {
 -	 ir_read_error(st, siglist, "Expected (signature ...)");
 -	 return NULL;
 -      }
 -
 -      read_function_sig(st, f, siglist, skip_body);
 +      s_expression *s_sig = (s_expression *) it.get();
 +      read_function_sig(f, s_sig, skip_body);
     }
     return added ? f : NULL;
  }
 -static void
 -read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,
 -		  bool skip_body)
 +void
 +ir_reader::read_function_sig(ir_function *f, s_expression *expr, bool skip_body)
  {
 -   void *ctx = st;
 -   if (list->length() != 4) {
 -      ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
 -			      "(<instruction> ...))");
 +   s_expression *type_expr;
 +   s_list *paramlist;
 +   s_list *body_list;
 +
 +   s_pattern pat[] = { "signature", type_expr, paramlist, body_list };
 +   if (!MATCH(expr, pat)) {
 +      ir_read_error(expr, "Expected (signature <type> (parameters ...) "
 +			  "(<instruction> ...))");
        return;
     }
 -   s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
 -   const glsl_type *return_type = read_type(st, type_expr);
 +   const glsl_type *return_type = read_type(type_expr);
     if (return_type == NULL)
        return;
 -   s_list *paramlist = SX_AS_LIST(type_expr->next);
 -   s_list *body_list = SX_AS_LIST(type_expr->next->next);
 -   if (paramlist == NULL || body_list == NULL) {
 -      ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
 -			      "(<instruction> ...))");
 -      return;
 -   }
     s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
     if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) {
 -      ir_read_error(st, paramlist, "Expected (parameters ...)");
 +      ir_read_error(paramlist, "Expected (parameters ...)");
        return;
     }
     // Read the parameters list into a temporary place.
     exec_list hir_parameters;
 -   st->symbols->push_scope();
 +   state->symbols->push_scope();
     exec_list_iterator it = paramlist->subexpressions.iterator();
     for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
 -      s_list *decl = SX_AS_LIST(it.get());
 -      ir_variable *var = read_declaration(st, decl);
 +      ir_variable *var = read_declaration((s_expression *) it.get());
        if (var == NULL)
  	 return;
 @@ -292,25 +253,25 @@ read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,     ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
     if (sig == NULL && skip_body) {
        /* If scanning for prototypes, generate a new signature. */
 -      sig = new(ctx) ir_function_signature(return_type);
 +      sig = new(mem_ctx) ir_function_signature(return_type);
        sig->is_builtin = true;
        f->add_signature(sig);
     } else if (sig != NULL) {
        const char *badvar = sig->qualifiers_match(&hir_parameters);
        if (badvar != NULL) {
 -	 ir_read_error(st, list, "function `%s' parameter `%s' qualifiers "
 +	 ir_read_error(expr, "function `%s' parameter `%s' qualifiers "
  		       "don't match prototype", f->name, badvar);
  	 return;
        }
        if (sig->return_type != return_type) {
 -	 ir_read_error(st, list, "function `%s' return type doesn't "
 +	 ir_read_error(expr, "function `%s' return type doesn't "
  		       "match prototype", f->name);
  	 return;
        }
     } else {
        /* No prototype for this body exists - skip it. */
 -      st->symbols->pop_scope();
 +      state->symbols->pop_scope();
        return;
     }
     assert(sig != NULL);
 @@ -319,39 +280,39 @@ read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,     if (!skip_body && !body_list->subexpressions.is_empty()) {
        if (sig->is_defined) {
 -	 ir_read_error(st, list, "function %s redefined", f->name);
 +	 ir_read_error(expr, "function %s redefined", f->name);
  	 return;
        }
 -      st->current_function = sig;
 -      read_instructions(st, &sig->body, body_list, NULL);
 -      st->current_function = NULL;
 +      state->current_function = sig;
 +      read_instructions(&sig->body, body_list, NULL);
 +      state->current_function = NULL;
        sig->is_defined = true;
     }
 -   st->symbols->pop_scope();
 +   state->symbols->pop_scope();
  }
 -static void
 -read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,
 -		  s_expression *expr, ir_loop *loop_ctx)
 +void
 +ir_reader::read_instructions(exec_list *instructions, s_expression *expr,
 +			     ir_loop *loop_ctx)
  {
     // Read in a list of instructions
     s_list *list = SX_AS_LIST(expr);
     if (list == NULL) {
 -      ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
 +      ir_read_error(expr, "Expected (<instruction> ...); found an atom.");
        return;
     }
     foreach_iter(exec_list_iterator, it, list->subexpressions) {
        s_expression *sub = (s_expression*) it.get();
 -      ir_instruction *ir = read_instruction(st, sub, loop_ctx);
 +      ir_instruction *ir = read_instruction(sub, loop_ctx);
        if (ir != NULL) {
  	 /* Global variable declarations should be moved to the top, before
  	  * any functions that might use them.  Functions are added to the
  	  * instruction stream when scanning for prototypes, so without this
  	  * hack, they always appear before variable declarations.
  	  */
 -	 if (st->current_function == NULL && ir->as_variable() != NULL)
 +	 if (state->current_function == NULL && ir->as_variable() != NULL)
  	    instructions->push_head(ir);
  	 else
  	    instructions->push_tail(ir);
 @@ -360,88 +321,74 @@ read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,  }
 -static ir_instruction *
 -read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
 -	         ir_loop *loop_ctx)
 +ir_instruction *
 +ir_reader::read_instruction(s_expression *expr, ir_loop *loop_ctx)
  {
 -   void *ctx = st;
     s_symbol *symbol = SX_AS_SYMBOL(expr);
     if (symbol != NULL) {
        if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
 -	 return new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
 +	 return new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break);
        if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
 -	 return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
 +	 return new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
     }
     s_list *list = SX_AS_LIST(expr);
     if (list == NULL || list->subexpressions.is_empty()) {
 -      ir_read_error(st, expr, "Invalid instruction.\n");
 +      ir_read_error(expr, "Invalid instruction.\n");
        return NULL;
     }
     s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
     if (tag == NULL) {
 -      ir_read_error(st, expr, "expected instruction tag");
 +      ir_read_error(expr, "expected instruction tag");
        return NULL;
     }
     ir_instruction *inst = NULL;
     if (strcmp(tag->value(), "declare") == 0) {
 -      inst = read_declaration(st, list);
 +      inst = read_declaration(list);
     } else if (strcmp(tag->value(), "assign") == 0) {
 -      inst = read_assignment(st, list);
 +      inst = read_assignment(list);
     } else if (strcmp(tag->value(), "if") == 0) {
 -      inst = read_if(st, list, loop_ctx);
 +      inst = read_if(list, loop_ctx);
     } else if (strcmp(tag->value(), "loop") == 0) {
 -      inst = read_loop(st, list);
 +      inst = read_loop(list);
     } else if (strcmp(tag->value(), "return") == 0) {
 -      inst = read_return(st, list);
 +      inst = read_return(list);
     } else if (strcmp(tag->value(), "function") == 0) {
 -      inst = read_function(st, list, false);
 +      inst = read_function(list, false);
     } else {
 -      inst = read_rvalue(st, list);
 +      inst = read_rvalue(list);
        if (inst == NULL)
 -	 ir_read_error(st, NULL, "when reading instruction");
 +	 ir_read_error(NULL, "when reading instruction");
     }
     return inst;
  }
 -
 -static ir_variable *
 -read_declaration(_mesa_glsl_parse_state *st, s_list *list)
 +ir_variable *
 +ir_reader::read_declaration(s_expression *expr)
  {
 -   void *ctx = st;
 -   if (list->length() != 4) {
 -      ir_read_error(st, list, "expected (declare (<qualifiers>) <type> "
 -			      "<name>)");
 -      return NULL;
 -   }
 +   s_list *s_quals;
 +   s_expression *s_type;
 +   s_symbol *s_name;
 -   s_list *quals = SX_AS_LIST(list->subexpressions.head->next);
 -   if (quals == NULL) {
 -      ir_read_error(st, list, "expected a list of variable qualifiers");
 +   s_pattern pat[] = { "declare", s_quals, s_type, s_name };
 +   if (!MATCH(expr, pat)) {
 +      ir_read_error(expr, "expected (declare (<qualifiers>) <type> <name>)");
        return NULL;
     }
 -   s_expression *type_expr = (s_expression*) quals->next;
 -   const glsl_type *type = read_type(st, type_expr);
 +   const glsl_type *type = read_type(s_type);
     if (type == NULL)
        return NULL;
 -   s_symbol *var_name = SX_AS_SYMBOL(type_expr->next);
 -   if (var_name == NULL) {
 -      ir_read_error(st, list, "expected variable name, found non-symbol");
 -      return NULL;
 -   }
 -
 -   ir_variable *var = new(ctx) ir_variable(type, var_name->value(),
 -					   ir_var_auto);
 +   ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(),
 +					       ir_var_auto);
 -   foreach_iter(exec_list_iterator, it, quals->subexpressions) {
 +   foreach_iter(exec_list_iterator, it, s_quals->subexpressions) {
        s_symbol *qualifier = SX_AS_SYMBOL(it.get());
        if (qualifier == NULL) {
 -	 ir_read_error(st, list, "qualifier list must contain only symbols");
 -	 delete var;
 +	 ir_read_error(expr, "qualifier list must contain only symbols");
  	 return NULL;
        }
 @@ -467,44 +414,42 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list)        } else if (strcmp(qualifier->value(), "noperspective") == 0) {
  	 var->interpolation = ir_var_noperspective;
        } else {
 -	 ir_read_error(st, list, "unknown qualifier: %s", qualifier->value());
 -	 delete var;
 +	 ir_read_error(expr, "unknown qualifier: %s", qualifier->value());
  	 return NULL;
        }
     }
     // Add the variable to the symbol table
 -   st->symbols->add_variable(var);
 +   state->symbols->add_variable(var);
     return var;
  }
 -static ir_if *
 -read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)
 +ir_if *
 +ir_reader::read_if(s_expression *expr, ir_loop *loop_ctx)
  {
 -   void *ctx = st;
 -   if (list->length() != 4) {
 -      ir_read_error(st, list, "expected (if <condition> (<then> ...) "
 -                          "(<else> ...))");
 +   s_expression *s_cond;
 +   s_expression *s_then;
 +   s_expression *s_else;
 +
 +   s_pattern pat[] = { "if", s_cond, s_then, s_else };
 +   if (!MATCH(expr, pat)) {
 +      ir_read_error(expr, "expected (if <condition> (<then>...) (<else>...))");
        return NULL;
     }
 -   s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
 -   ir_rvalue *condition = read_rvalue(st, cond_expr);
 +   ir_rvalue *condition = read_rvalue(s_cond);
     if (condition == NULL) {
 -      ir_read_error(st, NULL, "when reading condition of (if ...)");
 +      ir_read_error(NULL, "when reading condition of (if ...)");
        return NULL;
     }
 -   s_expression *then_expr = (s_expression*) cond_expr->next;
 -   s_expression *else_expr = (s_expression*) then_expr->next;
 +   ir_if *iff = new(mem_ctx) ir_if(condition);
 -   ir_if *iff = new(ctx) ir_if(condition);
 -
 -   read_instructions(st, &iff->then_instructions, then_expr, loop_ctx);
 -   read_instructions(st, &iff->else_instructions, else_expr, loop_ctx);
 -   if (st->error) {
 +   read_instructions(&iff->then_instructions, s_then, loop_ctx);
 +   read_instructions(&iff->else_instructions, s_else, loop_ctx);
 +   if (state->error) {
        delete iff;
        iff = NULL;
     }
 @@ -512,27 +457,23 @@ read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)  }
 -static ir_loop *
 -read_loop(_mesa_glsl_parse_state *st, s_list *list)
 +ir_loop *
 +ir_reader::read_loop(s_expression *expr)
  {
 -   void *ctx = st;
 -   if (list->length() != 6) {
 -      ir_read_error(st, list, "expected (loop <counter> <from> <to> "
 -			      "<increment> <body>)");
 +   s_expression *s_counter, *s_from, *s_to, *s_inc, *s_body;
 +
 +   s_pattern pat[] = { "loop", s_counter, s_from, s_to, s_inc, s_body };
 +   if (!MATCH(expr, pat)) {
 +      ir_read_error(expr, "expected (loop <counter> <from> <to> "
 +			  "<increment> <body>)");
        return NULL;
     }
 -   s_expression *count_expr = (s_expression*) list->subexpressions.head->next;
 -   s_expression *from_expr  = (s_expression*) count_expr->next;
 -   s_expression *to_expr    = (s_expression*) from_expr->next;
 -   s_expression *inc_expr   = (s_expression*) to_expr->next;
 -   s_expression *body_expr  = (s_expression*) inc_expr->next;
 -
     // FINISHME: actually read the count/from/to fields.
 -   ir_loop *loop = new(ctx) ir_loop;
 -   read_instructions(st, &loop->body_instructions, body_expr, loop);
 -   if (st->error) {
 +   ir_loop *loop = new(mem_ctx) ir_loop;
 +   read_instructions(&loop->body_instructions, s_body, loop);
 +   if (state->error) {
        delete loop;
        loop = NULL;
     }
 @@ -540,29 +481,29 @@ read_loop(_mesa_glsl_parse_state *st, s_list *list)  }
 -static ir_return *
 -read_return(_mesa_glsl_parse_state *st, s_list *list)
 +ir_return *
 +ir_reader::read_return(s_expression *expr)
  {
 -   void *ctx = st;
 -   if (list->length() != 2) {
 -      ir_read_error(st, list, "expected (return <rvalue>)");
 +   s_expression *s_retval;
 +
 +   s_pattern pat[] = { "return", s_retval};
 +   if (!MATCH(expr, pat)) {
 +      ir_read_error(expr, "expected (return <rvalue>)");
        return NULL;
     }
 -   s_expression *expr = (s_expression*) list->subexpressions.head->next;
 -
 -   ir_rvalue *retval = read_rvalue(st, expr);
 +   ir_rvalue *retval = read_rvalue(s_retval);
     if (retval == NULL) {
 -      ir_read_error(st, NULL, "when reading return value");
 +      ir_read_error(NULL, "when reading return value");
        return NULL;
     }
 -   return new(ctx) ir_return(retval);
 +   return new(mem_ctx) ir_return(retval);
  }
 -static ir_rvalue *
 -read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr)
 +ir_rvalue *
 +ir_reader::read_rvalue(s_expression *expr)
  {
     s_list *list = SX_AS_LIST(expr);
     if (list == NULL || list->subexpressions.is_empty())
 @@ -570,68 +511,63 @@ read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr)     s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
     if (tag == NULL) {
 -      ir_read_error(st, expr, "expected rvalue tag");
 +      ir_read_error(expr, "expected rvalue tag");
        return NULL;
     }
 -   ir_rvalue *rvalue = read_dereference(st, list);
 -   if (rvalue != NULL || st->error)
 +   ir_rvalue *rvalue = read_dereference(list);
 +   if (rvalue != NULL || state->error)
        return rvalue;
     else if (strcmp(tag->value(), "swiz") == 0) {
 -      rvalue = read_swizzle(st, list);
 +      rvalue = read_swizzle(list);
     } else if (strcmp(tag->value(), "expression") == 0) {
 -      rvalue = read_expression(st, list);
 +      rvalue = read_expression(list);
     } else if (strcmp(tag->value(), "call") == 0) {
 -      rvalue = read_call(st, list);
 +      rvalue = read_call(list);
     } else if (strcmp(tag->value(), "constant") == 0) {
 -      rvalue = read_constant(st, list);
 +      rvalue = read_constant(list);
     } else {
 -      rvalue = read_texture(st, list);
 -      if (rvalue == NULL && !st->error)
 -	 ir_read_error(st, expr, "unrecognized rvalue tag: %s", tag->value());
 +      rvalue = read_texture(list);
 +      if (rvalue == NULL && !state->error)
 +	 ir_read_error(expr, "unrecognized rvalue tag: %s", tag->value());
     }
     return rvalue;
  }
 -static ir_assignment *
 -read_assignment(_mesa_glsl_parse_state *st, s_list *list)
 +ir_assignment *
 +ir_reader::read_assignment(s_expression *expr)
  {
 -   void *ctx = st;
 -   if (list->length() != 5) {
 -      ir_read_error(st, list, "expected (assign <condition> (<write mask>) "
 -			      "<lhs> <rhs>)");
 -      return NULL;
 -   }
 -
 -   s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
 -   s_list       *mask_list = SX_AS_LIST(cond_expr->next);
 -   s_expression *lhs_expr  = (s_expression*) cond_expr->next->next;
 -   s_expression *rhs_expr  = (s_expression*) lhs_expr->next;
 +   s_expression *cond_expr = NULL;
 +   s_expression *lhs_expr, *rhs_expr;
 +   s_list       *mask_list;
 -   ir_rvalue *condition = read_rvalue(st, cond_expr);
 -   if (condition == NULL) {
 -      ir_read_error(st, NULL, "when reading condition of assignment");
 +   s_pattern pat4[] = { "assign",            mask_list, lhs_expr, rhs_expr };
 +   s_pattern pat5[] = { "assign", cond_expr, mask_list, lhs_expr, rhs_expr };
 +   if (!MATCH(expr, pat4) && !MATCH(expr, pat5)) {
 +      ir_read_error(expr, "expected (assign [<condition>] (<write mask>) "
 +			  "<lhs> <rhs>)");
        return NULL;
     }
 -   if (mask_list == NULL || mask_list->length() > 1) {
 -      ir_read_error(st, mask_list, "expected () or (<write mask>)");
 -      return NULL;
 +   ir_rvalue *condition = NULL;
 +   if (cond_expr != NULL) {
 +      condition = read_rvalue(cond_expr);
 +      if (condition == NULL) {
 +	 ir_read_error(NULL, "when reading condition of assignment");
 +	 return NULL;
 +      }
     }
     unsigned mask = 0;
 -   if (mask_list->length() == 1) {
 -      s_symbol *mask_symbol = SX_AS_SYMBOL(mask_list->subexpressions.head);
 -      if (mask_symbol == NULL) {
 -	 ir_read_error(st, list, "expected a write mask; found non-symbol");
 -	 return NULL;
 -      }
 +   s_symbol *mask_symbol;
 +   s_pattern mask_pat[] = { mask_symbol };
 +   if (MATCH(mask_list, mask_pat)) {
        const char *mask_str = mask_symbol->value();
        unsigned mask_length = strlen(mask_str);
        if (mask_length > 4) {
 -	 ir_read_error(st, list, "invalid write mask: %s", mask_str);
 +	 ir_read_error(expr, "invalid write mask: %s", mask_str);
  	 return NULL;
        }
 @@ -639,47 +575,46 @@ read_assignment(_mesa_glsl_parse_state *st, s_list *list)        for (unsigned i = 0; i < mask_length; i++) {
  	 if (mask_str[i] < 'w' || mask_str[i] > 'z') {
 -	    ir_read_error(st, list, "write mask contains invalid character: %c",
 +	    ir_read_error(expr, "write mask contains invalid character: %c",
  			  mask_str[i]);
  	    return NULL;
  	 }
  	 mask |= 1 << idx_map[mask_str[i] - 'w'];
        }
 +   } else if (!mask_list->subexpressions.is_empty()) {
 +      ir_read_error(mask_list, "expected () or (<write mask>)");
 +      return NULL;
     }
 -   ir_dereference *lhs = read_dereference(st, lhs_expr);
 +   ir_dereference *lhs = read_dereference(lhs_expr);
     if (lhs == NULL) {
 -      ir_read_error(st, NULL, "when reading left-hand side of assignment");
 +      ir_read_error(NULL, "when reading left-hand side of assignment");
        return NULL;
     }
 -   ir_rvalue *rhs = read_rvalue(st, rhs_expr);
 +   ir_rvalue *rhs = read_rvalue(rhs_expr);
     if (rhs == NULL) {
 -      ir_read_error(st, NULL, "when reading right-hand side of assignment");
 +      ir_read_error(NULL, "when reading right-hand side of assignment");
        return NULL;
     }
     if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) {
 -      ir_read_error(st, list, "non-zero write mask required.");
 +      ir_read_error(expr, "non-zero write mask required.");
        return NULL;
     }
 -   return new(ctx) ir_assignment(lhs, rhs, condition, mask);
 +   return new(mem_ctx) ir_assignment(lhs, rhs, condition, mask);
  }
 -static ir_call *
 -read_call(_mesa_glsl_parse_state *st, s_list *list)
 +ir_call *
 +ir_reader::read_call(s_expression *expr)
  {
 -   void *ctx = st;
 -   if (list->length() != 3) {
 -      ir_read_error(st, list, "expected (call <name> (<param> ...))");
 -      return NULL;
 -   }
 +   s_symbol *name;
 +   s_list *params;
 -   s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
 -   s_list *params = SX_AS_LIST(list->subexpressions.head->next->next);
 -   if (name == NULL || params == NULL) {
 -      ir_read_error(st, list, "expected (call <name> (<param> ...))");
 +   s_pattern pat[] = { "call", name, params };
 +   if (!MATCH(expr, pat)) {
 +      ir_read_error(expr, "expected (call <name> (<param> ...))");
        return NULL;
     }
 @@ -687,173 +622,156 @@ read_call(_mesa_glsl_parse_state *st, s_list *list)     foreach_iter(exec_list_iterator, it, params->subexpressions) {
        s_expression *expr = (s_expression*) it.get();
 -      ir_rvalue *param = read_rvalue(st, expr);
 +      ir_rvalue *param = read_rvalue(expr);
        if (param == NULL) {
 -	 ir_read_error(st, list, "when reading parameter to function call");
 +	 ir_read_error(expr, "when reading parameter to function call");
  	 return NULL;
        }
        parameters.push_tail(param);
     }
 -   ir_function *f = st->symbols->get_function(name->value());
 +   ir_function *f = state->symbols->get_function(name->value());
     if (f == NULL) {
 -      ir_read_error(st, list, "found call to undefined function %s",
 +      ir_read_error(expr, "found call to undefined function %s",
  		    name->value());
        return NULL;
     }
     ir_function_signature *callee = f->matching_signature(¶meters);
     if (callee == NULL) {
 -      ir_read_error(st, list, "couldn't find matching signature for function "
 +      ir_read_error(expr, "couldn't find matching signature for function "
                      "%s", name->value());
        return NULL;
     }
 -   return new(ctx) ir_call(callee, ¶meters);
 +   return new(mem_ctx) ir_call(callee, ¶meters);
  }
 -static ir_expression *
 -read_expression(_mesa_glsl_parse_state *st, s_list *list)
 +ir_expression *
 +ir_reader::read_expression(s_expression *expr)
  {
 -   void *ctx = st;
 -   const unsigned list_length = list->length();
 -   if (list_length < 4) {
 -      ir_read_error(st, list, "expected (expression <type> <operator> "
 -			      "<operand> [<operand>])");
 +   s_expression *s_type;
 +   s_symbol *s_op;
 +   s_expression *s_arg1;
 +
 +   s_pattern pat[] = { "expression", s_type, s_op, s_arg1 };
 +   if (!PARTIAL_MATCH(expr, pat)) {
 +      ir_read_error(expr, "expected (expression <type> <operator> "
 +			  "<operand> [<operand>])");
        return NULL;
     }
 +   s_expression *s_arg2 = (s_expression *) s_arg1->next; // may be tail sentinel
 -   s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
 -   const glsl_type *type = read_type(st, type_expr);
 +   const glsl_type *type = read_type(s_type);
     if (type == NULL)
        return NULL;
     /* Read the operator */
 -   s_symbol *op_sym = SX_AS_SYMBOL(type_expr->next);
 -   if (op_sym == NULL) {
 -      ir_read_error(st, list, "expected operator, found non-symbol");
 -      return NULL;
 -   }
 -
 -   ir_expression_operation op = ir_expression::get_operator(op_sym->value());
 +   ir_expression_operation op = ir_expression::get_operator(s_op->value());
     if (op == (ir_expression_operation) -1) {
 -      ir_read_error(st, list, "invalid operator: %s", op_sym->value());
 +      ir_read_error(expr, "invalid operator: %s", s_op->value());
        return NULL;
     }
 -   /* Now that we know the operator, check for the right number of operands */ 
 -   if (ir_expression::get_num_operands(op) == 2) {
 -      if (list_length != 5) {
 -	 ir_read_error(st, list, "expected (expression <type> %s <operand> "
 -				 " <operand>)", op_sym->value());
 -	 return NULL;
 -      }
 -   } else {
 -      if (list_length != 4) {
 -	 ir_read_error(st, list, "expected (expression <type> %s <operand>)",
 -		       op_sym->value());
 -	 return NULL;
 -      }
 +   unsigned num_operands = ir_expression::get_num_operands(op);
 +   if (num_operands == 1 && !s_arg1->next->is_tail_sentinel()) {
 +      ir_read_error(expr, "expected (expression <type> %s <operand>)",
 +		    s_op->value());
 +      return NULL;
     }
 -   s_expression *exp1 = (s_expression*) (op_sym->next);
 -   ir_rvalue *arg1 = read_rvalue(st, exp1);
 +   ir_rvalue *arg1 = read_rvalue(s_arg1);
 +   ir_rvalue *arg2 = NULL;
     if (arg1 == NULL) {
 -      ir_read_error(st, NULL, "when reading first operand of %s",
 -		    op_sym->value());
 +      ir_read_error(NULL, "when reading first operand of %s", s_op->value());
        return NULL;
     }
 -   ir_rvalue *arg2 = NULL;
 -   if (ir_expression::get_num_operands(op) == 2) {
 -      s_expression *exp2 = (s_expression*) (exp1->next);
 -      arg2 = read_rvalue(st, exp2);
 +   if (num_operands == 2) {
 +      if (s_arg2->is_tail_sentinel() || !s_arg2->next->is_tail_sentinel()) {
 +	 ir_read_error(expr, "expected (expression <type> %s <operand> "
 +			     "<operand>)", s_op->value());
 +	 return NULL;
 +      }
 +      arg2 = read_rvalue(s_arg2);
        if (arg2 == NULL) {
 -	 ir_read_error(st, NULL, "when reading second operand of %s",
 -		       op_sym->value());
 +	 ir_read_error(NULL, "when reading second operand of %s",
 +		       s_op->value());
  	 return NULL;
        }
     }
 -   return new(ctx) ir_expression(op, type, arg1, arg2);
 +   return new(mem_ctx) ir_expression(op, type, arg1, arg2);
  }
 -static ir_swizzle *
 -read_swizzle(_mesa_glsl_parse_state *st, s_list *list)
 +ir_swizzle *
 +ir_reader::read_swizzle(s_expression *expr)
  {
 -   if (list->length() != 3) {
 -      ir_read_error(st, list, "expected (swiz <swizzle> <rvalue>)");
 -      return NULL;
 -   }
 +   s_symbol *swiz;
 +   s_expression *sub;
 -   s_symbol *swiz = SX_AS_SYMBOL(list->subexpressions.head->next);
 -   if (swiz == NULL) {
 -      ir_read_error(st, list, "expected a valid swizzle; found non-symbol");
 +   s_pattern pat[] = { "swiz", swiz, sub };
 +   if (!MATCH(expr, pat)) {
 +      ir_read_error(expr, "expected (swiz <swizzle> <rvalue>)");
        return NULL;
     }
     if (strlen(swiz->value()) > 4) {
 -      ir_read_error(st, list, "expected a valid swizzle; found %s",
 -		    swiz->value());
 +      ir_read_error(expr, "expected a valid swizzle; found %s", swiz->value());
        return NULL;
     }
 -   s_expression *sub = (s_expression*) swiz->next;
 -   ir_rvalue *rvalue = read_rvalue(st, sub);
 +   ir_rvalue *rvalue = read_rvalue(sub);
     if (rvalue == NULL)
        return NULL;
     ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(),
  				       rvalue->type->vector_elements);
     if (ir == NULL)
 -      ir_read_error(st, list, "invalid swizzle");
 +      ir_read_error(expr, "invalid swizzle");
     return ir;
  }
 -static ir_constant *
 -read_constant(_mesa_glsl_parse_state *st, s_list *list)
 +ir_constant *
 +ir_reader::read_constant(s_expression *expr)
  {
 -   void *ctx = st;
 -   if (list->length() != 3) {
 -      ir_read_error(st, list, "expected (constant <type> (...))");
 +   s_expression *type_expr;
 +   s_list *values;
 +
 +   s_pattern pat[] = { "constant", type_expr, values };
 +   if (!MATCH(expr, pat)) {
 +      ir_read_error(expr, "expected (constant <type> (...))");
        return NULL;
     }
 -   s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
 -   const glsl_type *type = read_type(st, type_expr);
 +   const glsl_type *type = read_type(type_expr);
     if (type == NULL)
        return NULL;
 -   s_list *values = SX_AS_LIST(type_expr->next);
     if (values == NULL) {
 -      ir_read_error(st, list, "expected (constant <type> (...))");
 +      ir_read_error(expr, "expected (constant <type> (...))");
        return NULL;
     }
     if (type->is_array()) {
 -      const unsigned elements_supplied = values->length();
 -      if (elements_supplied != type->length) {
 -	 ir_read_error(st, values, "expected exactly %u array elements, "
 -		       "given %u", type->length, elements_supplied);
 -	 return NULL;
 -      }
 -
 +      unsigned elements_supplied = 0;
        exec_list elements;
        foreach_iter(exec_list_iterator, it, values->subexpressions) {
 -	 s_expression *expr = (s_expression *) it.get();
 -	 s_list *elt = SX_AS_LIST(expr);
 -	 if (elt == NULL) {
 -	    ir_read_error(st, expr, "expected (constant ...) array element");
 -	    return NULL;
 -	 }
 -
 -	 ir_constant *ir_elt = read_constant(st, elt);
 +	 s_expression *elt = (s_expression *) it.get();
 +	 ir_constant *ir_elt = read_constant(elt);
  	 if (ir_elt == NULL)
  	    return NULL;
  	 elements.push_tail(ir_elt);
 +	 elements_supplied++;
 +      }
 +
 +      if (elements_supplied != type->length) {
 +	 ir_read_error(values, "expected exactly %u array elements, "
 +		       "given %u", type->length, elements_supplied);
 +	 return NULL;
        }
 -      return new(ctx) ir_constant(type, &elements);
 +      return new(mem_ctx) ir_constant(type, &elements);
     }
     const glsl_type *const base_type = type->get_base_type();
 @@ -864,7 +782,7 @@ read_constant(_mesa_glsl_parse_state *st, s_list *list)     int k = 0;
     foreach_iter(exec_list_iterator, it, values->subexpressions) {
        if (k >= 16) {
 -	 ir_read_error(st, values, "expected at most 16 numbers");
 +	 ir_read_error(values, "expected at most 16 numbers");
  	 return NULL;
        }
 @@ -873,14 +791,14 @@ read_constant(_mesa_glsl_parse_state *st, s_list *list)        if (base_type->base_type == GLSL_TYPE_FLOAT) {
  	 s_number *value = SX_AS_NUMBER(expr);
  	 if (value == NULL) {
 -	    ir_read_error(st, values, "expected numbers");
 +	    ir_read_error(values, "expected numbers");
  	    return NULL;
  	 }
  	 data.f[k] = value->fvalue();
        } else {
  	 s_int *value = SX_AS_INT(expr);
  	 if (value == NULL) {
 -	    ir_read_error(st, values, "expected integers");
 +	    ir_read_error(values, "expected integers");
  	    return NULL;
  	 }
 @@ -898,246 +816,185 @@ read_constant(_mesa_glsl_parse_state *st, s_list *list)  	    break;
  	 }
  	 default:
 -	    ir_read_error(st, values, "unsupported constant type");
 +	    ir_read_error(values, "unsupported constant type");
  	    return NULL;
  	 }
        }
        ++k;
     }
 -   return new(ctx) ir_constant(type, &data);
 +   return new(mem_ctx) ir_constant(type, &data);
  }
 -static ir_dereference *
 -read_dereference(_mesa_glsl_parse_state *st, s_expression *expr)
 +ir_dereference *
 +ir_reader::read_dereference(s_expression *expr)
  {
 -   s_list *list = SX_AS_LIST(expr);
 -   if (list == NULL || list->subexpressions.is_empty())
 -      return NULL;
 -
 -   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
 -   assert(tag != NULL);
 -
 -   if (strcmp(tag->value(), "var_ref") == 0)
 -      return read_var_ref(st, list);
 -   if (strcmp(tag->value(), "array_ref") == 0)
 -      return read_array_ref(st, list);
 -   if (strcmp(tag->value(), "record_ref") == 0)
 -      return read_record_ref(st, list);
 -   return NULL;
 -}
 -
 -static ir_dereference_variable *
 -read_var_ref(_mesa_glsl_parse_state *st, s_list *list)
 -{
 -   void *ctx = st;
 -   if (list->length() != 2) {
 -      ir_read_error(st, list, "expected (var_ref <variable name>)");
 -      return NULL;
 -   }
 -   s_symbol *var_name = SX_AS_SYMBOL(list->subexpressions.head->next);
 -   if (var_name == NULL) {
 -      ir_read_error(st, list, "expected (var_ref <variable name>)");
 -      return NULL;
 -   }
 -
 -   ir_variable *var = st->symbols->get_variable(var_name->value());
 -   if (var == NULL) {
 -      ir_read_error(st, list, "undeclared variable: %s", var_name->value());
 -      return NULL;
 -   }
 -
 -   return new(ctx) ir_dereference_variable(var);
 -}
 -
 -static ir_dereference_array *
 -read_array_ref(_mesa_glsl_parse_state *st, s_list *list)
 -{
 -   void *ctx = st;
 -   if (list->length() != 3) {
 -      ir_read_error(st, list, "expected (array_ref <rvalue> <index>)");
 -      return NULL;
 -   }
 -
 -   s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
 -   ir_rvalue *subject = read_rvalue(st, subj_expr);
 -   if (subject == NULL) {
 -      ir_read_error(st, NULL, "when reading the subject of an array_ref");
 -      return NULL;
 -   }
 -
 -   s_expression *idx_expr = (s_expression*) subj_expr->next;
 -   ir_rvalue *idx = read_rvalue(st, idx_expr);
 -   return new(ctx) ir_dereference_array(subject, idx);
 -}
 -
 -static ir_dereference_record *
 -read_record_ref(_mesa_glsl_parse_state *st, s_list *list)
 -{
 -   void *ctx = st;
 -   if (list->length() != 3) {
 -      ir_read_error(st, list, "expected (record_ref <rvalue> <field>)");
 -      return NULL;
 -   }
 -
 -   s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
 -   ir_rvalue *subject = read_rvalue(st, subj_expr);
 -   if (subject == NULL) {
 -      ir_read_error(st, NULL, "when reading the subject of a record_ref");
 -      return NULL;
 -   }
 +   s_symbol *s_var;
 +   s_expression *s_subject;
 +   s_expression *s_index;
 +   s_symbol *s_field;
 +
 +   s_pattern var_pat[] = { "var_ref", s_var };
 +   s_pattern array_pat[] = { "array_ref", s_subject, s_index };
 +   s_pattern record_pat[] = { "record_ref", s_subject, s_field };
 +
 +   if (MATCH(expr, var_pat)) {
 +      ir_variable *var = state->symbols->get_variable(s_var->value());
 +      if (var == NULL) {
 +	 ir_read_error(expr, "undeclared variable: %s", s_var->value());
 +	 return NULL;
 +      }
 +      return new(mem_ctx) ir_dereference_variable(var);
 +   } else if (MATCH(expr, array_pat)) {
 +      ir_rvalue *subject = read_rvalue(s_subject);
 +      if (subject == NULL) {
 +	 ir_read_error(NULL, "when reading the subject of an array_ref");
 +	 return NULL;
 +      }
 -   s_symbol *field = SX_AS_SYMBOL(subj_expr->next);
 -   if (field == NULL) {
 -      ir_read_error(st, list, "expected (record_ref ... <field name>)");
 -      return NULL;
 +      ir_rvalue *idx = read_rvalue(s_index);
 +      if (subject == NULL) {
 +	 ir_read_error(NULL, "when reading the index of an array_ref");
 +	 return NULL;
 +      }
 +      return new(mem_ctx) ir_dereference_array(subject, idx);
 +   } else if (MATCH(expr, record_pat)) {
 +      ir_rvalue *subject = read_rvalue(s_subject);
 +      if (subject == NULL) {
 +	 ir_read_error(NULL, "when reading the subject of a record_ref");
 +	 return NULL;
 +      }
 +      return new(mem_ctx) ir_dereference_record(subject, s_field->value());
     }
 -   return new(ctx) ir_dereference_record(subject, field->value());
 -}
 -
 -static bool
 -valid_texture_list_length(ir_texture_opcode op, s_list *list)
 -{
 -   unsigned required_length = 7;
 -   if (op == ir_txf)
 -      required_length = 5;
 -   else if (op == ir_tex)
 -      required_length = 6;
 -
 -   return list->length() == required_length;
 +   return NULL;
  }
 -static ir_texture *
 -read_texture(_mesa_glsl_parse_state *st, s_list *list)
 +ir_texture *
 +ir_reader::read_texture(s_expression *expr)
  {
 -   void *ctx = st;
 -   s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
 -   assert(tag != NULL);
 -
 -   ir_texture_opcode op = ir_texture::get_opcode(tag->value());
 -   if (op == (ir_texture_opcode) -1)
 -      return NULL;
 -
 -   if (!valid_texture_list_length(op, list)) {
 -      ir_read_error(st, NULL, "invalid list size in (%s ...)", tag->value());
 -      return NULL;
 +   s_symbol *tag = NULL;
 +   s_expression *s_sampler = NULL;
 +   s_expression *s_coord = NULL;
 +   s_list *s_offset = NULL;
 +   s_expression *s_proj = NULL;
 +   s_list *s_shadow = NULL;
 +   s_expression *s_lod = NULL;
 +
 +   ir_texture_opcode op;
 +
 +   s_pattern tex_pattern[] =
 +      { "tex", s_sampler, s_coord, s_offset, s_proj, s_shadow };
 +   s_pattern txf_pattern[] =
 +      { "txf", s_sampler, s_coord, s_offset, s_lod };
 +   s_pattern other_pattern[] =
 +      { tag, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod };
 +
 +   if (MATCH(expr, tex_pattern)) {
 +      op = ir_tex;
 +   } else if (MATCH(expr, txf_pattern)) {
 +      op = ir_txf;
 +   } else if (MATCH(expr, other_pattern)) {
 +      op = ir_texture::get_opcode(tag->value());
 +      if (op == -1)
 +	 return NULL;
     }
 -   ir_texture *tex = new(ctx) ir_texture(op);
 +   ir_texture *tex = new(mem_ctx) ir_texture(op);
     // Read sampler (must be a deref)
 -   s_expression *sampler_expr = (s_expression *) tag->next;
 -   ir_dereference *sampler = read_dereference(st, sampler_expr);
 +   ir_dereference *sampler = read_dereference(s_sampler);
     if (sampler == NULL) {
 -      ir_read_error(st, NULL, "when reading sampler in (%s ...)", tag->value());
 +      ir_read_error(NULL, "when reading sampler in (%s ...)",
 +		    tex->opcode_string());
        return NULL;
     }
     tex->set_sampler(sampler);
     // Read coordinate (any rvalue)
 -   s_expression *coordinate_expr = (s_expression *) sampler_expr->next;
 -   tex->coordinate = read_rvalue(st, coordinate_expr);
 +   tex->coordinate = read_rvalue(s_coord);
     if (tex->coordinate == NULL) {
 -      ir_read_error(st, NULL, "when reading coordinate in (%s ...)",
 -		    tag->value());
 +      ir_read_error(NULL, "when reading coordinate in (%s ...)",
 +		    tex->opcode_string());
        return NULL;
     }
     // Read texel offset, i.e. (0 0 0)
 -   s_list *offset_list = SX_AS_LIST(coordinate_expr->next);
 -   if (offset_list == NULL || offset_list->length() != 3) {
 -      ir_read_error(st, offset_list, "expected (<int> <int> <int>)");
 -      return NULL;
 -   }
 -   s_int *offset_x = SX_AS_INT(offset_list->subexpressions.head);
 -   s_int *offset_y = SX_AS_INT(offset_list->subexpressions.head->next);
 -   s_int *offset_z = SX_AS_INT(offset_list->subexpressions.head->next->next);
 -   if (offset_x == NULL || offset_y == NULL || offset_z == NULL) {
 -      ir_read_error(st, offset_list, "expected (<int> <int> <int>)");
 +   s_int *offset_x;
 +   s_int *offset_y;
 +   s_int *offset_z;
 +   s_pattern offset_pat[] = { offset_x, offset_y, offset_z };
 +   if (!MATCH(s_offset, offset_pat)) {
 +      ir_read_error(s_offset, "expected (<int> <int> <int>)");
        return NULL;
     }
     tex->offsets[0] = offset_x->value();
     tex->offsets[1] = offset_y->value();
     tex->offsets[2] = offset_z->value();
 -   if (op == ir_txf) {
 -      s_expression *lod_expr = (s_expression *) offset_list->next;
 -      tex->lod_info.lod = read_rvalue(st, lod_expr);
 -      if (tex->lod_info.lod == NULL) {
 -	 ir_read_error(st, NULL, "when reading LOD in (txf ...)");
 -	 return NULL;
 -      }
 -   } else {
 -      s_expression *proj_expr = (s_expression *) offset_list->next;
 -      s_int *proj_as_int = SX_AS_INT(proj_expr);
 +   if (op != ir_txf) {
 +      s_int *proj_as_int = SX_AS_INT(s_proj);
        if (proj_as_int && proj_as_int->value() == 1) {
  	 tex->projector = NULL;
        } else {
 -	 tex->projector = read_rvalue(st, proj_expr);
 +	 tex->projector = read_rvalue(s_proj);
  	 if (tex->projector == NULL) {
 -	    ir_read_error(st, NULL, "when reading projective divide in (%s ..)",
 -	                  tag->value());
 +	    ir_read_error(NULL, "when reading projective divide in (%s ..)",
 +	                  tex->opcode_string());
  	    return NULL;
  	 }
        }
 -      s_list *shadow_list = SX_AS_LIST(proj_expr->next);
 -      if (shadow_list == NULL) {
 -	 ir_read_error(st, NULL, "shadow comparitor must be a list");
 -	 return NULL;
 -      }
 -      if (shadow_list->subexpressions.is_empty()) {
 -	 tex->shadow_comparitor= NULL;
 +      if (s_shadow->subexpressions.is_empty()) {
 +	 tex->shadow_comparitor = NULL;
        } else {
 -	 tex->shadow_comparitor = read_rvalue(st, shadow_list);
 +	 tex->shadow_comparitor = read_rvalue(s_shadow);
  	 if (tex->shadow_comparitor == NULL) {
 -	    ir_read_error(st, NULL, "when reading shadow comparitor in (%s ..)",
 -			  tag->value());
 +	    ir_read_error(NULL, "when reading shadow comparitor in (%s ..)",
 +			  tex->opcode_string());
  	    return NULL;
  	 }
        }
 -      s_expression *lod_expr = (s_expression *) shadow_list->next;
 -
 -      switch (op) {
 -      case ir_txb:
 -	 tex->lod_info.bias = read_rvalue(st, lod_expr);
 -	 if (tex->lod_info.bias == NULL) {
 -	    ir_read_error(st, NULL, "when reading LOD bias in (txb ...)");
 -	    return NULL;
 -	 }
 -	 break;
 -      case ir_txl:
 -	 tex->lod_info.lod = read_rvalue(st, lod_expr);
 -	 if (tex->lod_info.lod == NULL) {
 -	    ir_read_error(st, NULL, "when reading LOD in (txl ...)");
 -	    return NULL;
 -	 }
 -	 break;
 -      case ir_txd: {
 -	 s_list *lod_list = SX_AS_LIST(lod_expr);
 -	 if (lod_list->length() != 2) {
 -	    ir_read_error(st, lod_expr, "expected (dPdx dPdy) in (txd ...)");
 -	    return NULL;
 -	 }
 -	 s_expression *dx_expr = (s_expression *) lod_list->subexpressions.head;
 -	 s_expression *dy_expr = (s_expression *) dx_expr->next;
 +   }
 -	 tex->lod_info.grad.dPdx = read_rvalue(st, dx_expr);
 -	 if (tex->lod_info.grad.dPdx == NULL) {
 -	    ir_read_error(st, NULL, "when reading dPdx in (txd ...)");
 -	    return NULL;
 -	 }
 -	 tex->lod_info.grad.dPdy = read_rvalue(st, dy_expr);
 -	 if (tex->lod_info.grad.dPdy == NULL) {
 -	    ir_read_error(st, NULL, "when reading dPdy in (txd ...)");
 -	    return NULL;
 -	 }
 -	 break;
 +   switch (op) {
 +   case ir_txb:
 +      tex->lod_info.bias = read_rvalue(s_lod);
 +      if (tex->lod_info.bias == NULL) {
 +	 ir_read_error(NULL, "when reading LOD bias in (txb ...)");
 +	 return NULL;
 +      }
 +      break;
 +   case ir_txl:
 +   case ir_txf:
 +      tex->lod_info.lod = read_rvalue(s_lod);
 +      if (tex->lod_info.lod == NULL) {
 +	 ir_read_error(NULL, "when reading LOD in (%s ...)",
 +		       tex->opcode_string());
 +	 return NULL;
 +      }
 +      break;
 +   case ir_txd: {
 +      s_expression *s_dx, *s_dy;
 +      s_pattern dxdy_pat[] = { s_dx, s_dy };
 +      if (!MATCH(s_lod, dxdy_pat)) {
 +	 ir_read_error(s_lod, "expected (dPdx dPdy) in (txd ...)");
 +	 return NULL;
 +      }
 +      tex->lod_info.grad.dPdx = read_rvalue(s_dx);
 +      if (tex->lod_info.grad.dPdx == NULL) {
 +	 ir_read_error(NULL, "when reading dPdx in (txd ...)");
 +	 return NULL;
 +      }
 +      tex->lod_info.grad.dPdy = read_rvalue(s_dy);
 +      if (tex->lod_info.grad.dPdy == NULL) {
 +	 ir_read_error(NULL, "when reading dPdy in (txd ...)");
 +	 return NULL;
        }
 -      default:
 -	 // tex doesn't have any extra parameters and txf was handled earlier.
 -	 break;
 -      };
 +      break;
     }
 +   default:
 +      // tex doesn't have any extra parameters.
 +      break;
 +   };
     return tex;
  }
 diff --git a/mesalib/src/glsl/lower_jumps.cpp b/mesalib/src/glsl/lower_jumps.cpp index 7c3463e58..17be39f5b 100644 --- a/mesalib/src/glsl/lower_jumps.cpp +++ b/mesalib/src/glsl/lower_jumps.cpp @@ -66,7 +66,7 @@ enum jump_strength     strength_always_clears_execute_flag,
     strength_continue,
     strength_break,
 -   strength_return,
 +   strength_return
  };
  struct block_record
 diff --git a/mesalib/src/glsl/s_expression.cpp b/mesalib/src/glsl/s_expression.cpp index 0aecfa19c..36624541b 100644 --- a/mesalib/src/glsl/s_expression.cpp +++ b/mesalib/src/glsl/s_expression.cpp @@ -38,14 +38,15 @@ s_list::s_list()  {
  }
 -unsigned
 -s_list::length() const
 +static void
 +skip_whitespace(const char *& src)
  {
 -   unsigned i = 0;
 -   foreach_iter(exec_list_iterator, it, this->subexpressions) {
 -      i++;
 +   src += strspn(src, " \v\t\r\n");
 +   /* Also skip Scheme-style comments: semi-colon 'til end of line */
 +   if (src[0] == ';') {
 +      src += strcspn(src, "\n");
 +      skip_whitespace(src);
     }
 -   return i;
  }
  static s_expression *
 @@ -53,10 +54,9 @@ read_atom(void *ctx, const char *& src)  {
     s_expression *expr = NULL;
 -   // Skip leading spaces.
 -   src += strspn(src, " \v\t\r\n");
 +   skip_whitespace(src);
 -   size_t n = strcspn(src, "( \v\t\r\n)");
 +   size_t n = strcspn(src, "( \v\t\r\n);");
     if (n == 0)
        return NULL; // no atom
 @@ -90,8 +90,7 @@ s_expression::read_expression(void *ctx, const char *&src)     if (atom != NULL)
        return atom;
 -   // Skip leading spaces.
 -   src += strspn(src, " \v\t\r\n");
 +   skip_whitespace(src);
     if (src[0] == '(') {
        ++src;
 @@ -101,7 +100,7 @@ s_expression::read_expression(void *ctx, const char *&src)        while ((expr = read_expression(ctx, src)) != NULL) {
  	 list->subexpressions.push_tail(expr);
        }
 -      src += strspn(src, " \v\t\r\n");
 +      skip_whitespace(src);
        if (src[0] != ')') {
  	 printf("Unclosed expression (check your parenthesis).\n");
  	 return NULL;
 @@ -139,3 +138,49 @@ void s_list::print()     printf(")");
  }
 +// --------------------------------------------------
 +
 +bool
 +s_pattern::match(s_expression *expr)
 +{
 +   switch (type)
 +   {
 +   case EXPR:   *p_expr = expr; break;
 +   case LIST:   if (expr->is_list())   *p_list   = (s_list *)   expr; break;
 +   case SYMBOL: if (expr->is_symbol()) *p_symbol = (s_symbol *) expr; break;
 +   case NUMBER: if (expr->is_number()) *p_number = (s_number *) expr; break;
 +   case INT:    if (expr->is_int())    *p_int    = (s_int *)    expr; break;
 +   case STRING:
 +      s_symbol *sym = SX_AS_SYMBOL(expr);
 +      if (sym != NULL && strcmp(sym->value(), literal) == 0)
 +	 return true;
 +      return false;
 +   };
 +
 +   return *p_expr == expr;
 +}
 +
 +bool
 +s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial)
 +{
 +   s_list *list = SX_AS_LIST(top);
 +   if (list == NULL)
 +      return false;
 +
 +   unsigned i = 0;
 +   foreach_iter(exec_list_iterator, it, list->subexpressions) {
 +      if (i >= n)
 +	 return partial; /* More actual items than the pattern expected */
 +
 +      s_expression *expr = (s_expression *) it.get();
 +      if (expr == NULL || !pattern[i].match(expr))
 +	 return false;
 +
 +      i++;
 +   }
 +
 +   if (i < n)
 +      return false; /* Less actual items than the pattern expected */
 +
 +   return true;
 +}
 diff --git a/mesalib/src/glsl/s_expression.h b/mesalib/src/glsl/s_expression.h index 6b5e52f5a..1bb437736 100644 --- a/mesalib/src/glsl/s_expression.h +++ b/mesalib/src/glsl/s_expression.h @@ -26,9 +26,11 @@  #ifndef S_EXPRESSION_H
  #define S_EXPRESSION_H
 +#include "main/core.h" /* for Elements */
  #include "strtod.h"
  #include "list.h"
 +/* Type-safe downcasting macros (also safe to pass NULL) */
  #define SX_AS_(t,x) ((x) && ((s_expression*) x)->is_##t()) ? ((s_##t*) (x)) \
                                                             : NULL
  #define SX_AS_LIST(x)   SX_AS_(list, x)
 @@ -36,6 +38,10 @@  #define SX_AS_NUMBER(x) SX_AS_(number, x)
  #define SX_AS_INT(x)    SX_AS_(int, x)
 +/* Pattern matching macros */
 +#define MATCH(list, pat) s_match(list, Elements(pat), pat, false)
 +#define PARTIAL_MATCH(list, pat) s_match(list, Elements(pat), pat, true)
 +
  /* For our purposes, S-Expressions are:
   * - <int>
   * - <float>
 @@ -133,11 +139,42 @@ public:     s_list();
     virtual bool is_list() const { return true; }
 -   unsigned length() const;
     void print();
     exec_list subexpressions;
  };
 +// ------------------------------------------------------------
 +
 +/**
 + * Part of a pattern to match - essentially a record holding a pointer to the
 + * storage for the component to match, along with the appropriate type.
 + */
 +class s_pattern {
 +public:
 +   s_pattern(s_expression *&s) : p_expr(&s),   type(EXPR)   { }
 +   s_pattern(s_list       *&s) : p_list(&s),   type(LIST)   { }
 +   s_pattern(s_symbol     *&s) : p_symbol(&s), type(SYMBOL) { }
 +   s_pattern(s_number     *&s) : p_number(&s), type(NUMBER) { }
 +   s_pattern(s_int        *&s) : p_int(&s),    type(INT)    { }
 +   s_pattern(const char *str)  : literal(str), type(STRING) { }
 +
 +   bool match(s_expression *expr);
 +
 +private:
 +   union {
 +      s_expression **p_expr;
 +      s_list       **p_list;
 +      s_symbol     **p_symbol;
 +      s_number     **p_number;
 +      s_int        **p_int;
 +      const char *literal;
 +   };
 +   enum { EXPR, LIST, SYMBOL, NUMBER, INT, STRING } type;
 +};
 +
 +bool
 +s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial);
 +
  #endif /* S_EXPRESSION_H */
 diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index 3bf782a1b..8b3b55e5e 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -790,6 +790,9 @@ driCreateNewScreen(int scrn,      static const __DRIextension *emptyExtensionList[] = { NULL };
      __DRIscreen *psp;
 +    if (driDriverAPI.InitScreen == NULL)
 +	return NULL;
 +
      psp = calloc(1, sizeof *psp);
      if (!psp)
  	return NULL;
 diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 4b656a70f..57267b0d3 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -24,6 +24,12 @@   */
 +/**
 + * \file
 + * \brief Extension handling
 + */
 +
 +
  #include "glheader.h"
  #include "imports.h"
  #include "context.h"
 @@ -31,200 +37,334 @@  #include "mfeatures.h"
  #include "mtypes.h"
 +enum {
 +   DISABLE = 0,
 +   GL  = 1 << API_OPENGL,
 +   ES1 = 1 << API_OPENGLES,
 +   ES2 = 1 << API_OPENGLES2,
 +};
 -#define F(x) offsetof(struct gl_extensions, x)
 -#define ON GL_TRUE
 -#define OFF GL_FALSE
 +/**
 + * \brief An element of the \c extension_table.
 + */
 +struct extension {
 +   /** Name of extension, such as "GL_ARB_depth_clamp". */
 +   const char *name;
 +   /** Offset (in bytes) of the corresponding member in struct gl_extensions. */
 +   size_t offset;
 -/*
 +   /** Set of API's in which the extension exists, as a bitset. */
 +   uint8_t api_set;
 +};
 +
 +
 +/**
 + * Given a member \c x of struct gl_extensions, return offset of
 + * \c x in bytes.
 + */
 +#define o(x) offsetof(struct gl_extensions, x)
 +
 +
 +/**
 + * \brief Table of supported OpenGL extensions for all API's.
 + *
   * Note: The GL_MESAX_* extensions are placeholders for future ARB extensions.
   */
 -static const struct {
 -   GLboolean enabled;
 -   const char *name;
 -   int flag_offset;
 -} default_extensions[] = {
 -   { OFF, "GL_ARB_blend_func_extended",        F(ARB_blend_func_extended) },
 -   { ON,  "GL_ARB_copy_buffer",                F(ARB_copy_buffer) },
 -   { OFF, "GL_ARB_depth_buffer_float",         F(ARB_depth_buffer_float) },
 -   { OFF, "GL_ARB_depth_clamp",                F(ARB_depth_clamp) },
 -   { OFF, "GL_ARB_depth_texture",              F(ARB_depth_texture) },
 -   { ON,  "GL_ARB_draw_buffers",               F(ARB_draw_buffers) },
 -   { OFF, "GL_ARB_draw_elements_base_vertex",  F(ARB_draw_elements_base_vertex) },
 -   { OFF, "GL_ARB_draw_instanced",             F(ARB_draw_instanced) },
 -   { OFF, "GL_ARB_explicit_attrib_location",   F(ARB_explicit_attrib_location) },
 -   { OFF, "GL_ARB_fragment_coord_conventions", F(ARB_fragment_coord_conventions) },
 -   { OFF, "GL_ARB_fragment_program",           F(ARB_fragment_program) },
 -   { OFF, "GL_ARB_fragment_program_shadow",    F(ARB_fragment_program_shadow) },
 -   { OFF, "GL_ARB_fragment_shader",            F(ARB_fragment_shader) },
 -   { OFF, "GL_ARB_framebuffer_object",         F(ARB_framebuffer_object) },
 -   /* TODO: reenable this when the new GLSL compiler actually supports them */
 -   /* { OFF, "GL_ARB_geometry_shader4",           F(ARB_geometry_shader4) }, */
 -   { OFF, "GL_ARB_half_float_pixel",           F(ARB_half_float_pixel) },
 -   { OFF, "GL_ARB_half_float_vertex",          F(ARB_half_float_vertex) },
 -   { OFF, "GL_ARB_instanced_arrays",           F(ARB_instanced_arrays) },
 -   { OFF, "GL_ARB_map_buffer_range",           F(ARB_map_buffer_range) },
 -   { ON,  "GL_ARB_multisample",                F(ARB_multisample) },
 -   { OFF, "GL_ARB_multitexture",               F(ARB_multitexture) },
 -   { OFF, "GL_ARB_occlusion_query",            F(ARB_occlusion_query) },
 -   { OFF, "GL_ARB_occlusion_query2",           F(ARB_occlusion_query2) },
 -   { OFF, "GL_ARB_pixel_buffer_object",        F(EXT_pixel_buffer_object) },
 -   { OFF, "GL_ARB_point_parameters",           F(EXT_point_parameters) },
 -   { OFF, "GL_ARB_point_sprite",               F(ARB_point_sprite) },
 -   { OFF, "GL_ARB_provoking_vertex",           F(EXT_provoking_vertex) },
 -   { OFF, "GL_ARB_sampler_objects",            F(ARB_sampler_objects) },
 -   { OFF, "GL_ARB_seamless_cube_map",          F(ARB_seamless_cube_map) },
 -   { OFF, "GL_ARB_shader_objects",             F(ARB_shader_objects) },
 -   { OFF, "GL_ARB_shader_stencil_export",      F(ARB_shader_stencil_export) },
 -   { OFF, "GL_ARB_shading_language_100",       F(ARB_shading_language_100) },
 -   { OFF, "GL_ARB_shadow",                     F(ARB_shadow) },
 -   { OFF, "GL_ARB_shadow_ambient",             F(ARB_shadow_ambient) },
 -   { OFF, "GL_ARB_sync",                       F(ARB_sync) },
 -   { OFF, "GL_ARB_texture_border_clamp",       F(ARB_texture_border_clamp) },
 -   { OFF, "GL_ARB_texture_buffer_object",      F(ARB_texture_buffer_object) },
 -   { ON,  "GL_ARB_texture_compression",        F(ARB_texture_compression) },
 -   { OFF, "GL_ARB_texture_compression_rgtc",   F(ARB_texture_compression_rgtc) },
 -   { OFF, "GL_ARB_texture_cube_map",           F(ARB_texture_cube_map) },
 -   { OFF, "GL_ARB_texture_env_add",            F(EXT_texture_env_add) },
 -   { OFF, "GL_ARB_texture_env_combine",        F(ARB_texture_env_combine) },
 -   { OFF, "GL_ARB_texture_env_crossbar",       F(ARB_texture_env_crossbar) },
 -   { OFF, "GL_ARB_texture_env_dot3",           F(ARB_texture_env_dot3) },
 -   { OFF, "GL_MESAX_texture_float",            F(ARB_texture_float) },
 -   { OFF, "GL_ARB_texture_mirrored_repeat",    F(ARB_texture_mirrored_repeat)},
 -   { OFF, "GL_ARB_texture_multisample",        F(ARB_texture_multisample) },
 -   { OFF, "GL_ARB_texture_non_power_of_two",   F(ARB_texture_non_power_of_two)},
 -   { OFF, "GL_ARB_texture_rectangle",          F(NV_texture_rectangle) },
 -   { OFF, "GL_ARB_texture_rg",                 F(ARB_texture_rg) },
 -   { OFF, "GL_ARB_texture_rgb10_a2ui",         F(ARB_texture_rgb10_a2ui) },
 -   { OFF, "GL_ARB_texture_swizzle",            F(EXT_texture_swizzle) },
 -   { ON,  "GL_ARB_transpose_matrix",           F(ARB_transpose_matrix) },
 -   { OFF, "GL_ARB_transform_feedback2",        F(ARB_transform_feedback2) },
 -   { OFF, "GL_ARB_uniform_buffer_object",      F(ARB_uniform_buffer_object) },
 -   { OFF, "GL_ARB_vertex_array_bgra",          F(EXT_vertex_array_bgra) },
 -   { OFF, "GL_ARB_vertex_array_object",        F(ARB_vertex_array_object) },
 -   { ON,  "GL_ARB_vertex_buffer_object",       F(ARB_vertex_buffer_object) },
 -   { OFF, "GL_ARB_vertex_program",             F(ARB_vertex_program) },
 -   { OFF, "GL_ARB_vertex_shader",              F(ARB_vertex_shader) },
 -   { OFF, "GL_ARB_vertex_type_2_10_10_10_rev", F(ARB_vertex_type_2_10_10_10_rev) },
 -   { ON,  "GL_ARB_window_pos",                 F(ARB_window_pos) },
 -   { ON,  "GL_EXT_abgr",                       F(EXT_abgr) },
 -   { ON,  "GL_EXT_bgra",                       F(EXT_bgra) },
 -   { OFF, "GL_EXT_blend_color",                F(EXT_blend_color) },
 -   { OFF, "GL_EXT_blend_equation_separate",    F(EXT_blend_equation_separate) },
 -   { OFF, "GL_EXT_blend_func_separate",        F(EXT_blend_func_separate) },
 -   { OFF, "GL_EXT_blend_logic_op",             F(EXT_blend_logic_op) },
 -   { OFF, "GL_EXT_blend_minmax",               F(EXT_blend_minmax) },
 -   { OFF, "GL_EXT_blend_subtract",             F(EXT_blend_subtract) },
 -   { OFF, "GL_EXT_clip_volume_hint",           F(EXT_clip_volume_hint) },
 -   { ON,  "GL_EXT_compiled_vertex_array",      F(EXT_compiled_vertex_array) },
 -   { 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) },
 -   { OFF, "GL_EXT_draw_instanced",             F(ARB_draw_instanced) },
 -   { 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) },
 -   { OFF, "GL_EXT_framebuffer_object",         F(EXT_framebuffer_object) },
 -   { OFF, "GL_EXT_framebuffer_sRGB",           F(EXT_framebuffer_sRGB) },
 -   { OFF, "GL_EXT_fog_coord",                  F(EXT_fog_coord) },
 -   { OFF, "GL_EXT_gpu_program_parameters",     F(EXT_gpu_program_parameters) },
 -   { OFF, "GL_EXT_gpu_shader4",                F(EXT_gpu_shader4) },
 -   { ON,  "GL_EXT_multi_draw_arrays",          F(EXT_multi_draw_arrays) },
 -   { OFF, "GL_EXT_packed_depth_stencil",       F(EXT_packed_depth_stencil) },
 -   { OFF, "GL_EXT_packed_float",               F(EXT_packed_float) },
 -   { ON,  "GL_EXT_packed_pixels",              F(EXT_packed_pixels) },
 -   { OFF, "GL_EXT_paletted_texture",           F(EXT_paletted_texture) },
 -   { OFF, "GL_EXT_pixel_buffer_object",        F(EXT_pixel_buffer_object) },
 -   { OFF, "GL_EXT_point_parameters",           F(EXT_point_parameters) },
 -   { ON,  "GL_EXT_polygon_offset",             F(EXT_polygon_offset) },
 -   { OFF, "GL_EXT_provoking_vertex",           F(EXT_provoking_vertex) },
 -   { ON,  "GL_EXT_rescale_normal",             F(EXT_rescale_normal) },
 -   { OFF, "GL_EXT_secondary_color",            F(EXT_secondary_color) },
 -   { OFF, "GL_EXT_separate_shader_objects",    F(EXT_separate_shader_objects) },
 -   { ON,  "GL_EXT_separate_specular_color",    F(EXT_separate_specular_color) },
 -   { OFF, "GL_EXT_shadow_funcs",               F(EXT_shadow_funcs) },
 -   { OFF, "GL_EXT_shared_texture_palette",     F(EXT_shared_texture_palette) },
 -   { OFF, "GL_EXT_stencil_two_side",           F(EXT_stencil_two_side) },
 -   { OFF, "GL_EXT_stencil_wrap",               F(EXT_stencil_wrap) },
 -   { ON,  "GL_EXT_subtexture",                 F(EXT_subtexture) },
 -   { ON,  "GL_EXT_texture",                    F(EXT_texture) },
 -   { ON,  "GL_EXT_texture3D",                  F(EXT_texture3D) },
 -   { OFF, "GL_EXT_texture_array",              F(EXT_texture_array) },
 -   { OFF, "GL_EXT_texture_compression_s3tc",   F(EXT_texture_compression_s3tc) },
 -   { OFF, "GL_EXT_texture_compression_rgtc",   F(ARB_texture_compression_rgtc) },
 -   { OFF, "GL_EXT_texture_cube_map",           F(ARB_texture_cube_map) },
 -   { ON,  "GL_EXT_texture_edge_clamp",         F(SGIS_texture_edge_clamp) },
 -   { OFF, "GL_EXT_texture_env_add",            F(EXT_texture_env_add) },
 -   { OFF, "GL_EXT_texture_env_combine",        F(EXT_texture_env_combine) },
 -   { OFF, "GL_EXT_texture_env_dot3",           F(EXT_texture_env_dot3) },
 -   { OFF, "GL_EXT_texture_filter_anisotropic", F(EXT_texture_filter_anisotropic) },
 -   { OFF, "GL_EXT_texture_integer",            F(EXT_texture_integer) },
 -   { OFF, "GL_EXT_texture_lod_bias",           F(EXT_texture_lod_bias) },
 -   { OFF, "GL_EXT_texture_mirror_clamp",       F(EXT_texture_mirror_clamp) },
 -   { ON,  "GL_EXT_texture_object",             F(EXT_texture_object) },
 -   { OFF, "GL_EXT_texture_rectangle",          F(NV_texture_rectangle) },
 -   { OFF, "GL_EXT_texture_shared_exponent",    F(EXT_texture_shared_exponent) },
 -   { OFF, "GL_EXT_texture_sRGB",               F(EXT_texture_sRGB) },
 -   { OFF, "GL_EXT_texture_swizzle",            F(EXT_texture_swizzle) },
 -   { OFF, "GL_EXT_timer_query",                F(EXT_timer_query) },
 -   { OFF, "GL_EXT_transform_feedback",         F(EXT_transform_feedback) },
 -   { ON,  "GL_EXT_vertex_array",               F(EXT_vertex_array) },
 -   { OFF, "GL_EXT_vertex_array_bgra",          F(EXT_vertex_array_bgra) },
 -   { OFF, "GL_EXT_vertex_array_set",           F(EXT_vertex_array_set) },
 -   { OFF, "GL_3DFX_texture_compression_FXT1",  F(TDFX_texture_compression_FXT1) },
 -   { OFF, "GL_APPLE_client_storage",           F(APPLE_client_storage) },
 -   { ON,  "GL_APPLE_packed_pixels",            F(APPLE_packed_pixels) },
 -   { OFF, "GL_APPLE_vertex_array_object",      F(APPLE_vertex_array_object) },
 -   { OFF, "GL_APPLE_object_purgeable",         F(APPLE_object_purgeable) },
 -   { OFF, "GL_ATI_blend_equation_separate",    F(EXT_blend_equation_separate) },
 -   { OFF, "GL_ATI_envmap_bumpmap",             F(ATI_envmap_bumpmap) },
 -   { OFF, "GL_ATI_texture_env_combine3",       F(ATI_texture_env_combine3)},
 -   { OFF, "GL_ATI_texture_mirror_once",        F(ATI_texture_mirror_once)},
 -   { OFF, "GL_ATI_fragment_shader",            F(ATI_fragment_shader)},
 -   { OFF, "GL_ATI_separate_stencil",           F(ATI_separate_stencil)},
 -   { ON,  "GL_IBM_multimode_draw_arrays",      F(IBM_multimode_draw_arrays) },
 -   { ON,  "GL_IBM_rasterpos_clip",             F(IBM_rasterpos_clip) },
 -   { OFF, "GL_IBM_texture_mirrored_repeat",    F(ARB_texture_mirrored_repeat)},
 -   { OFF, "GL_INGR_blend_func_separate",       F(EXT_blend_func_separate) },
 -   { OFF, "GL_MESA_pack_invert",               F(MESA_pack_invert) },
 -   { OFF, "GL_MESA_resize_buffers",            F(MESA_resize_buffers) },
 -   { OFF, "GL_MESA_texture_array",             F(MESA_texture_array) },
 -   { OFF, "GL_MESA_texture_signed_rgba",       F(MESA_texture_signed_rgba) },
 -   { OFF, "GL_MESA_ycbcr_texture",             F(MESA_ycbcr_texture) },
 -   { ON,  "GL_MESA_window_pos",                F(ARB_window_pos) },
 -   { OFF, "GL_NV_blend_square",                F(NV_blend_square) },
 -   { OFF, "GL_NV_conditional_render",          F(NV_conditional_render) },
 -   { OFF, "GL_NV_depth_clamp",                 F(ARB_depth_clamp) },
 -   { OFF, "GL_NV_fragment_program",            F(NV_fragment_program) },
 -   { OFF, "GL_NV_fragment_program_option",     F(NV_fragment_program_option) },
 -   { ON,  "GL_NV_light_max_exponent",          F(NV_light_max_exponent) },
 -   { OFF, "GL_NV_packed_depth_stencil",        F(EXT_packed_depth_stencil) },
 -   { OFF, "GL_NV_point_sprite",                F(NV_point_sprite) },
 -   { OFF, "GL_NV_primitive_restart",           F(NV_primitive_restart) },
 -   { ON,  "GL_NV_texgen_reflection",           F(NV_texgen_reflection) },
 -   { OFF, "GL_NV_texture_env_combine4",        F(NV_texture_env_combine4) },
 -   { OFF, "GL_NV_texture_rectangle",           F(NV_texture_rectangle) },
 -   { OFF, "GL_NV_vertex_program",              F(NV_vertex_program) },
 -   { OFF, "GL_NV_vertex_program1_1",           F(NV_vertex_program1_1) },
 -   { ON,  "GL_OES_read_format",                F(OES_read_format) },
 -   { OFF, "GL_SGI_texture_color_table",        F(SGI_texture_color_table) },
 -   { ON,  "GL_SGIS_generate_mipmap",           F(SGIS_generate_mipmap) },
 -   { OFF, "GL_SGIS_texture_border_clamp",      F(ARB_texture_border_clamp) },
 -   { ON,  "GL_SGIS_texture_edge_clamp",        F(SGIS_texture_edge_clamp) },
 -   { ON,  "GL_SGIS_texture_lod",               F(SGIS_texture_lod) },
 -   { ON,  "GL_SUN_multi_draw_arrays",          F(EXT_multi_draw_arrays) },
 -   { OFF, "GL_S3_s3tc",                        F(S3_s3tc) },
 -   { OFF, "GL_EXT_texture_format_BGRA8888",    F(EXT_texture_format_BGRA8888) },
 -#if FEATURE_OES_EGL_image
 -   { OFF, "GL_OES_EGL_image",                  F(OES_EGL_image) },
 -#endif
 +static const struct extension extension_table[] = {
 +   /* ARB Extensions */
 +   { "GL_ARB_blend_func_extended",                 o(ARB_blend_func_extended),                 GL             },
 +   { "GL_ARB_copy_buffer",                         o(ARB_copy_buffer),                         GL             },
 +   { "GL_ARB_depth_buffer_float",                  o(ARB_depth_buffer_float),                  GL             },
 +   { "GL_ARB_depth_clamp",                         o(ARB_depth_clamp),                         GL             },
 +   { "GL_ARB_depth_texture",                       o(ARB_depth_texture),                       GL             },
 +   { "GL_ARB_draw_buffers",                        o(ARB_draw_buffers),                        GL             },
 +   { "GL_ARB_draw_elements_base_vertex",           o(ARB_draw_elements_base_vertex),           GL             },
 +   { "GL_ARB_draw_instanced",                      o(ARB_draw_instanced),                      GL             },
 +   { "GL_ARB_explicit_attrib_location",            o(ARB_explicit_attrib_location),            GL             },
 +   { "GL_ARB_fragment_coord_conventions",          o(ARB_fragment_coord_conventions),          GL             },
 +   { "GL_ARB_fragment_program",                    o(ARB_fragment_program),                    GL             },
 +   { "GL_ARB_fragment_program_shadow",             o(ARB_fragment_program_shadow),             GL             },
 +   { "GL_ARB_fragment_shader",                     o(ARB_fragment_shader),                     GL             },
 +   { "GL_ARB_framebuffer_object",                  o(ARB_framebuffer_object),                  GL             },
 +   { "GL_ARB_half_float_pixel",                    o(ARB_half_float_pixel),                    GL             },
 +   { "GL_ARB_half_float_vertex",                   o(ARB_half_float_vertex),                   GL             },
 +   { "GL_ARB_instanced_arrays",                    o(ARB_instanced_arrays),                    GL             },
 +   { "GL_ARB_map_buffer_range",                    o(ARB_map_buffer_range),                    GL             },
 +   { "GL_ARB_multisample",                         o(ARB_multisample),                         GL             },
 +   { "GL_ARB_multitexture",                        o(ARB_multitexture),                        GL             },
 +   { "GL_ARB_occlusion_query2",                    o(ARB_occlusion_query2),                    GL             },
 +   { "GL_ARB_occlusion_query",                     o(ARB_occlusion_query),                     GL             },
 +   { "GL_ARB_pixel_buffer_object",                 o(EXT_pixel_buffer_object),                 GL             },
 +   { "GL_ARB_point_parameters",                    o(EXT_point_parameters),                    GL             },
 +   { "GL_ARB_point_sprite",                        o(ARB_point_sprite),                        GL             },
 +   { "GL_ARB_provoking_vertex",                    o(EXT_provoking_vertex),                    GL             },
 +   { "GL_ARB_sampler_objects",                     o(ARB_sampler_objects),                     GL             },
 +   { "GL_ARB_seamless_cube_map",                   o(ARB_seamless_cube_map),                   GL             },
 +   { "GL_ARB_shader_objects",                      o(ARB_shader_objects),                      GL             },
 +   { "GL_ARB_shader_stencil_export",               o(ARB_shader_stencil_export),               GL             },
 +   { "GL_ARB_shading_language_100",                o(ARB_shading_language_100),                GL             },
 +   { "GL_ARB_shadow_ambient",                      o(ARB_shadow_ambient),                      GL             },
 +   { "GL_ARB_shadow",                              o(ARB_shadow),                              GL             },
 +   { "GL_ARB_sync",                                o(ARB_sync),                                GL             },
 +   { "GL_ARB_texture_border_clamp",                o(ARB_texture_border_clamp),                GL             },
 +   { "GL_ARB_texture_buffer_object",               o(ARB_texture_buffer_object),               GL             },
 +   { "GL_ARB_texture_compression",                 o(ARB_texture_compression),                 GL             },
 +   { "GL_ARB_texture_compression_rgtc",            o(ARB_texture_compression_rgtc),            GL             },
 +   { "GL_ARB_texture_cube_map",                    o(ARB_texture_cube_map),                    GL             },
 +   { "GL_ARB_texture_env_add",                     o(EXT_texture_env_add),                     GL             },
 +   { "GL_ARB_texture_env_combine",                 o(ARB_texture_env_combine),                 GL             },
 +   { "GL_ARB_texture_env_crossbar",                o(ARB_texture_env_crossbar),                GL             },
 +   { "GL_ARB_texture_env_dot3",                    o(ARB_texture_env_dot3),                    GL             },
 +   { "GL_ARB_texture_mirrored_repeat",             o(ARB_texture_mirrored_repeat),             GL             },
 +   { "GL_ARB_texture_multisample",                 o(ARB_texture_multisample),                 GL             },
 +   { "GL_ARB_texture_non_power_of_two",            o(ARB_texture_non_power_of_two),            GL             },
 +   { "GL_ARB_texture_rectangle",                   o(NV_texture_rectangle),                    GL             },
 +   { "GL_ARB_texture_rgb10_a2ui",                  o(ARB_texture_rgb10_a2ui),                  GL             },
 +   { "GL_ARB_texture_rg",                          o(ARB_texture_rg),                          GL             },
 +   { "GL_ARB_texture_swizzle",                     o(EXT_texture_swizzle),                     GL             },
 +   { "GL_ARB_transform_feedback2",                 o(ARB_transform_feedback2),                 GL             },
 +   { "GL_ARB_transpose_matrix",                    o(ARB_transpose_matrix),                    GL             },
 +   { "GL_ARB_uniform_buffer_object",               o(ARB_uniform_buffer_object),               GL             },
 +   { "GL_ARB_vertex_array_bgra",                   o(EXT_vertex_array_bgra),                   GL             },
 +   { "GL_ARB_vertex_array_object",                 o(ARB_vertex_array_object),                 GL             },
 +   { "GL_ARB_vertex_buffer_object",                o(ARB_vertex_buffer_object),                GL             },
 +   { "GL_ARB_vertex_program",                      o(ARB_vertex_program),                      GL             },
 +   { "GL_ARB_vertex_shader",                       o(ARB_vertex_shader),                       GL             },
 +   { "GL_ARB_vertex_type_2_10_10_10_rev",          o(ARB_vertex_type_2_10_10_10_rev),          GL             },
 +   { "GL_ARB_window_pos",                          o(ARB_window_pos),                          GL             },
 +
 +   /* EXT extensions */
 +   { "GL_EXT_abgr",                                o(EXT_abgr),                                GL             },
 +   { "GL_EXT_bgra",                                o(EXT_bgra),                                GL             },
 +   { "GL_EXT_blend_color",                         o(EXT_blend_color),                         GL             },
 +   { "GL_EXT_blend_equation_separate",             o(EXT_blend_equation_separate),             GL             },
 +   { "GL_EXT_blend_func_separate",                 o(EXT_blend_func_separate),                 GL             },
 +   { "GL_EXT_blend_logic_op",                      o(EXT_blend_logic_op),                      GL             },
 +   { "GL_EXT_blend_minmax",                        o(EXT_blend_minmax),                        GL | ES1 | ES2 },
 +   { "GL_EXT_blend_subtract",                      o(EXT_blend_subtract),                      GL             },
 +   { "GL_EXT_clip_volume_hint",                    o(EXT_clip_volume_hint),                    GL             },
 +   { "GL_EXT_compiled_vertex_array",               o(EXT_compiled_vertex_array),               GL             },
 +   { "GL_EXT_copy_texture",                        o(EXT_copy_texture),                        GL             },
 +   { "GL_EXT_depth_bounds_test",                   o(EXT_depth_bounds_test),                   GL             },
 +   { "GL_EXT_draw_buffers2",                       o(EXT_draw_buffers2),                       GL             },
 +   { "GL_EXT_draw_instanced",                      o(ARB_draw_instanced),                      GL             },
 +   { "GL_EXT_draw_range_elements",                 o(EXT_draw_range_elements),                 GL             },
 +   { "GL_EXT_fog_coord",                           o(EXT_fog_coord),                           GL             },
 +   { "GL_EXT_framebuffer_blit",                    o(EXT_framebuffer_blit),                    GL             },
 +   { "GL_EXT_framebuffer_multisample",             o(EXT_framebuffer_multisample),             GL             },
 +   { "GL_EXT_framebuffer_object",                  o(EXT_framebuffer_object),                  GL             },
 +   { "GL_EXT_framebuffer_sRGB",                    o(EXT_framebuffer_sRGB),                    GL             },
 +   { "GL_EXT_gpu_program_parameters",              o(EXT_gpu_program_parameters),              GL             },
 +   { "GL_EXT_gpu_shader4",                         o(EXT_gpu_shader4),                         GL             },
 +   { "GL_EXT_multi_draw_arrays",                   o(EXT_multi_draw_arrays),                   GL | ES1 | ES2 },
 +   { "GL_EXT_packed_depth_stencil",                o(EXT_packed_depth_stencil),                GL             },
 +   { "GL_EXT_packed_float",                        o(EXT_packed_float),                        GL             },
 +   { "GL_EXT_packed_pixels",                       o(EXT_packed_pixels),                       GL             },
 +   { "GL_EXT_paletted_texture",                    o(EXT_paletted_texture),                    GL             },
 +   { "GL_EXT_pixel_buffer_object",                 o(EXT_pixel_buffer_object),                 GL             },
 +   { "GL_EXT_point_parameters",                    o(EXT_point_parameters),                    GL             },
 +   { "GL_EXT_polygon_offset",                      o(EXT_polygon_offset),                      GL             },
 +   { "GL_EXT_provoking_vertex",                    o(EXT_provoking_vertex),                    GL             },
 +   { "GL_EXT_rescale_normal",                      o(EXT_rescale_normal),                      GL             },
 +   { "GL_EXT_secondary_color",                     o(EXT_secondary_color),                     GL             },
 +   { "GL_EXT_separate_shader_objects",             o(EXT_separate_shader_objects),             GL             },
 +   { "GL_EXT_separate_specular_color",             o(EXT_separate_specular_color),             GL             },
 +   { "GL_EXT_shadow_funcs",                        o(EXT_shadow_funcs),                        GL             },
 +   { "GL_EXT_shared_texture_palette",              o(EXT_shared_texture_palette),              GL             },
 +   { "GL_EXT_stencil_two_side",                    o(EXT_stencil_two_side),                    GL             },
 +   { "GL_EXT_stencil_wrap",                        o(EXT_stencil_wrap),                        GL             },
 +   { "GL_EXT_subtexture",                          o(EXT_subtexture),                          GL             },
 +   { "GL_EXT_texture3D",                           o(EXT_texture3D),                           GL             },
 +   { "GL_EXT_texture_array",                       o(EXT_texture_array),                       GL             },
 +   { "GL_EXT_texture_compression_dxt1",            o(EXT_texture_compression_s3tc),            GL | ES1 | ES2 },
 +   { "GL_EXT_texture_compression_rgtc",            o(ARB_texture_compression_rgtc),            GL             },
 +   { "GL_EXT_texture_compression_s3tc",            o(EXT_texture_compression_s3tc),            GL             },
 +   { "GL_EXT_texture_cube_map",                    o(ARB_texture_cube_map),                    GL             },
 +   { "GL_EXT_texture_edge_clamp",                  o(SGIS_texture_edge_clamp),                 GL             },
 +   { "GL_EXT_texture_env_add",                     o(EXT_texture_env_add),                     GL             },
 +   { "GL_EXT_texture_env_combine",                 o(EXT_texture_env_combine),                 GL             },
 +   { "GL_EXT_texture_env_dot3",                    o(EXT_texture_env_dot3),                    GL             },
 +   { "GL_EXT_texture_filter_anisotropic",          o(EXT_texture_filter_anisotropic),          GL | ES1 | ES2 },
 +   { "GL_EXT_texture_format_BGRA8888",             o(EXT_texture_format_BGRA8888),                  ES1 | ES2 },
 +   { "GL_EXT_texture_integer",                     o(EXT_texture_integer),                     GL             },
 +   { "GL_EXT_texture_lod_bias",                    o(EXT_texture_lod_bias),                    GL | ES1       },
 +   { "GL_EXT_texture_mirror_clamp",                o(EXT_texture_mirror_clamp),                GL             },
 +   { "GL_EXT_texture_object",                      o(EXT_texture_object),                      GL             },
 +   { "GL_EXT_texture",                             o(EXT_texture),                             GL             },
 +   { "GL_EXT_texture_rectangle",                   o(NV_texture_rectangle),                    GL             },
 +   { "GL_EXT_texture_shared_exponent",             o(EXT_texture_shared_exponent),             GL             },
 +   { "GL_EXT_texture_sRGB",                        o(EXT_texture_sRGB),                        GL             },
 +   { "GL_EXT_texture_swizzle",                     o(EXT_texture_swizzle),                     GL             },
 +   { "GL_EXT_texture_type_2_10_10_10_REV",         o(dummy_true),                                         ES2 },
 +   { "GL_EXT_timer_query",                         o(EXT_timer_query),                         GL             },
 +   { "GL_EXT_transform_feedback",                  o(EXT_transform_feedback),                  GL             },
 +   { "GL_EXT_vertex_array_bgra",                   o(EXT_vertex_array_bgra),                   GL             },
 +   { "GL_EXT_vertex_array",                        o(EXT_vertex_array),                        GL             },
 +   { "GL_EXT_vertex_array_set",                    o(EXT_vertex_array_set),                    GL             },
 +
 +   /* OES extensions */
 +   { "GL_OES_blend_equation_separate",             o(EXT_blend_equation_separate),                  ES1       },
 +   { "GL_OES_blend_func_separate",                 o(EXT_blend_func_separate),                      ES1       },
 +   { "GL_OES_blend_subtract",                      o(EXT_blend_subtract),                           ES1       },
 +   { "GL_OES_byte_coordinates",                    o(dummy_true),                                   ES1       },
 +   { "GL_OES_compressed_paletted_texture",         o(dummy_false),                     DISABLE                },
 +   { "GL_OES_depth24",                             o(EXT_framebuffer_object),                       ES1 | ES2 },
 +   { "GL_OES_depth32",                             o(dummy_false),                     DISABLE                },
 +   { "GL_OES_depth_texture",                       o(ARB_depth_texture),                                  ES2 },
  #if FEATURE_OES_draw_texture
 -   { OFF, "GL_OES_draw_texture",               F(OES_draw_texture) },
 -#endif /* FEATURE_OES_draw_texture */
 +   { "GL_OES_draw_texture",                        o(OES_draw_texture),                             ES1 | ES2 },
 +#endif
 +#if FEATURE_OES_EGL_image
 +   /*  FIXME: Mesa expects GL_OES_EGL_image to be available in OpenGL contexts. */
 +   { "GL_OES_EGL_image",                           o(OES_EGL_image),                           GL | ES1 | ES2 },
 +#endif
 +   { "GL_OES_element_index_uint",                  o(EXT_vertex_array),                             ES1 | ES2 },
 +   { "GL_OES_fbo_render_mipmap",                   o(EXT_framebuffer_object),                       ES1 | ES2 },
 +   { "GL_OES_fixed_point",                         o(dummy_true),                                   ES1       },
 +   { "GL_OES_framebuffer_object",                  o(EXT_framebuffer_object),                       ES1       },
 +   { "GL_OES_mapbuffer",                           o(ARB_vertex_buffer_object),                     ES1 | ES2 },
 +   { "GL_OES_matrix_get",                          o(dummy_true),                                   ES1       },
 +   { "GL_OES_packed_depth_stencil",                o(EXT_packed_depth_stencil),                     ES1 | ES2 },
 +   { "GL_OES_point_size_array",                    o(dummy_true),                                   ES1       },
 +   { "GL_OES_point_sprite",                        o(ARB_point_sprite),                             ES1       },
 +   { "GL_OES_query_matrix",                        o(dummy_true),                                   ES1       },
 +   { "GL_OES_read_format",                         o(OES_read_format),                         GL | ES1       },
 +   { "GL_OES_rgb8_rgba8",                          o(EXT_framebuffer_object),                       ES1 | ES2 },
 +   { "GL_OES_single_precision",                    o(dummy_true),                                   ES1       },
 +   { "GL_OES_standard_derivatives",                o(ARB_fragment_shader),                                ES2 },
 +   { "GL_OES_stencil1",                            o(dummy_false),                     DISABLE                },
 +   { "GL_OES_stencil4",                            o(dummy_false),                     DISABLE                },
 +   { "GL_OES_stencil8",                            o(EXT_framebuffer_object),                       ES1 | ES2 },
 +   { "GL_OES_stencil_wrap",                        o(EXT_stencil_wrap),                             ES1       },
 +   /* GL_OES_texture_3D is disabled due to missing GLSL support. */
 +   { "GL_OES_texture_3D",                          o(EXT_texture3D),                   DISABLE                },
 +   { "GL_OES_texture_cube_map",                    o(ARB_texture_cube_map),                         ES1       },
 +   { "GL_OES_texture_env_crossbar",                o(ARB_texture_env_crossbar),                     ES1       },
 +   { "GL_OES_texture_mirrored_repeat",             o(ARB_texture_mirrored_repeat),                  ES1       },
 +   { "GL_OES_texture_npot",                        o(ARB_texture_non_power_of_two),                       ES2 },
 +
 +   /* Vendor extensions */
 +   { "GL_3DFX_texture_compression_FXT1",           o(TDFX_texture_compression_FXT1),           GL             },
 +   { "GL_APPLE_client_storage",                    o(APPLE_client_storage),                    GL             },
 +   { "GL_APPLE_object_purgeable",                  o(APPLE_object_purgeable),                  GL             },
 +   { "GL_APPLE_packed_pixels",                     o(APPLE_packed_pixels),                     GL             },
 +   { "GL_APPLE_vertex_array_object",               o(APPLE_vertex_array_object),               GL             },
 +   { "GL_ATI_blend_equation_separate",             o(EXT_blend_equation_separate),             GL             },
 +   { "GL_ATI_envmap_bumpmap",                      o(ATI_envmap_bumpmap),                      GL             },
 +   { "GL_ATI_fragment_shader",                     o(ATI_fragment_shader),                     GL             },
 +   { "GL_ATI_separate_stencil",                    o(ATI_separate_stencil),                    GL             },
 +   { "GL_ATI_texture_env_combine3",                o(ATI_texture_env_combine3),                GL             },
 +   { "GL_ATI_texture_mirror_once",                 o(ATI_texture_mirror_once),                 GL             },
 +   { "GL_IBM_multimode_draw_arrays",               o(IBM_multimode_draw_arrays),               GL             },
 +   { "GL_IBM_rasterpos_clip",                      o(IBM_rasterpos_clip),                      GL             },
 +   { "GL_IBM_texture_mirrored_repeat",             o(ARB_texture_mirrored_repeat),             GL             },
 +   { "GL_INGR_blend_func_separate",                o(EXT_blend_func_separate),                 GL             },
 +   { "GL_MESA_pack_invert",                        o(MESA_pack_invert),                        GL             },
 +   { "GL_MESA_resize_buffers",                     o(MESA_resize_buffers),                     GL             },
 +   { "GL_MESA_texture_array",                      o(MESA_texture_array),                      GL             },
 +   { "GL_MESA_texture_signed_rgba",                o(MESA_texture_signed_rgba),                GL             },
 +   { "GL_MESA_window_pos",                         o(ARB_window_pos),                          GL             },
 +   { "GL_MESAX_texture_float",                     o(ARB_texture_float),                       GL             },
 +   { "GL_MESA_ycbcr_texture",                      o(MESA_ycbcr_texture),                      GL             },
 +   { "GL_NV_blend_square",                         o(NV_blend_square),                         GL             },
 +   { "GL_NV_conditional_render",                   o(NV_conditional_render),                   GL             },
 +   { "GL_NV_depth_clamp",                          o(ARB_depth_clamp),                         GL             },
 +   { "GL_NV_fragment_program",                     o(NV_fragment_program),                     GL             },
 +   { "GL_NV_fragment_program_option",              o(NV_fragment_program_option),              GL             },
 +   { "GL_NV_light_max_exponent",                   o(NV_light_max_exponent),                   GL             },
 +   { "GL_NV_packed_depth_stencil",                 o(EXT_packed_depth_stencil),                GL             },
 +   { "GL_NV_point_sprite",                         o(NV_point_sprite),                         GL             },
 +   { "GL_NV_primitive_restart",                    o(NV_primitive_restart),                    GL             },
 +   { "GL_NV_texgen_reflection",                    o(NV_texgen_reflection),                    GL             },
 +   { "GL_NV_texture_env_combine4",                 o(NV_texture_env_combine4),                 GL             },
 +   { "GL_NV_texture_rectangle",                    o(NV_texture_rectangle),                    GL             },
 +   { "GL_NV_vertex_program1_1",                    o(NV_vertex_program1_1),                    GL             },
 +   { "GL_NV_vertex_program",                       o(NV_vertex_program),                       GL             },
 +   { "GL_S3_s3tc",                                 o(S3_s3tc),                                 GL             },
 +   { "GL_SGIS_generate_mipmap",                    o(SGIS_generate_mipmap),                    GL             },
 +   { "GL_SGIS_texture_border_clamp",               o(ARB_texture_border_clamp),                GL             },
 +   { "GL_SGIS_texture_edge_clamp",                 o(SGIS_texture_edge_clamp),                 GL             },
 +   { "GL_SGIS_texture_lod",                        o(SGIS_texture_lod),                        GL             },
 +   { "GL_SGI_texture_color_table",                 o(SGI_texture_color_table),                 GL             },
 +   { "GL_SUN_multi_draw_arrays",                   o(EXT_multi_draw_arrays),                   GL             },
 +
 +   { 0, 0, 0 },
  };
 +/**
 + * Given an extension name, lookup up the corresponding member of struct
 + * gl_extensions and return that member's offset (in bytes).  If the name is
 + * not found in the \c extension_table, return 0.
 + *
 + * \param name Name of extension.
 + * \return Offset of member in struct gl_extensions.
 + */
 +static size_t
 +name_to_offset(const char* name)
 +{
 +   const struct extension *i;
 +
 +   if (name == 0)
 +      return 0;
 +
 +   for (i = extension_table; i->name != 0; ++i) {
 +      if (strcmp(name, i->name) == 0)
 +	 return i->offset;
 +   }
 +
 +   return 0;
 +}
 +
 +
 +/**
 + * \brief Extensions enabled by default.
 + *
 + * These extensions are enabled by _mesa_init_extensions().
 + *
 + * XXX: Should these defaults also apply to GLES?
 + */
 +static const size_t default_extensions[] = {
 +   o(ARB_copy_buffer),
 +   o(ARB_draw_buffers),
 +   o(ARB_multisample),
 +   o(ARB_texture_compression),
 +   o(ARB_transpose_matrix),
 +   o(ARB_vertex_buffer_object),
 +   o(ARB_window_pos),
 +
 +   o(EXT_abgr),
 +   o(EXT_bgra),
 +   o(EXT_compiled_vertex_array),
 +   o(EXT_copy_texture),
 +   o(EXT_draw_range_elements),
 +   o(EXT_multi_draw_arrays),
 +   o(EXT_packed_pixels),
 +   o(EXT_polygon_offset),
 +   o(EXT_rescale_normal),
 +   o(EXT_separate_specular_color),
 +   o(EXT_subtexture),
 +   o(EXT_texture),
 +   o(EXT_texture3D),
 +   o(EXT_texture_object),
 +   o(EXT_vertex_array),
 +
 +   o(OES_read_format),
 +
 +   /* Vendor Extensions */
 +   o(APPLE_packed_pixels),
 +   o(IBM_multimode_draw_arrays),
 +   o(IBM_rasterpos_clip),
 +   o(NV_light_max_exponent),
 +   o(NV_texgen_reflection),
 +   o(SGIS_generate_mipmap),
 +   o(SGIS_texture_edge_clamp),
 +   o(SGIS_texture_lod),
 +
 +   0,
 +};
 +
  /**
   * Enable all extensions suitable for a software-only renderer.
 @@ -513,8 +653,7 @@ _mesa_enable_2_1_extensions(struct gl_context *ctx)  static GLboolean
  set_extension( struct gl_context *ctx, const char *name, GLboolean state )
  {
 -   GLboolean *base = (GLboolean *) &ctx->Extensions;
 -   GLuint i;
 +   size_t offset;
     if (ctx->Extensions.String) {
        /* The string was already queried - can't change it now! */
 @@ -522,16 +661,20 @@ set_extension( struct gl_context *ctx, const char *name, GLboolean state )        return GL_FALSE;
     }
 -   for (i = 0 ; i < Elements(default_extensions) ; i++) {
 -      if (strcmp(default_extensions[i].name, name) == 0) {
 -         if (default_extensions[i].flag_offset) {
 -            GLboolean *enabled = base + default_extensions[i].flag_offset;
 -            *enabled = state;
 -         }
 -         return GL_TRUE;
 -      }
 +   offset = name_to_offset(name);
 +   if (offset == 0) {
 +      _mesa_problem(ctx, "Trying to enable/disable unknown extension %s",
 +	            name);
 +      return GL_FALSE;
 +   } else if (offset == o(dummy_true) && state == GL_FALSE) {
 +      _mesa_problem(ctx, "Trying to disable a permanently enabled extension: "
 +	                  "%s", name);
 +      return GL_FALSE;
 +   } else {
 +      GLboolean *base = (GLboolean *) &ctx->Extensions;
 +      base[offset] = state;
 +      return GL_TRUE;
     }
 -   return GL_FALSE;
  }
 @@ -560,36 +703,22 @@ _mesa_disable_extension( struct gl_context *ctx, const char *name )  /**
 - * Check if the i-th extension is enabled.
 - */
 -static GLboolean
 -extension_enabled(struct gl_context *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( struct gl_context *ctx, const char *name )
  {
 -   GLuint i;
 +   size_t offset;
 +   GLboolean *base;
 -   for (i = 0 ; i < Elements(default_extensions) ; i++) {
 -      if (strcmp(default_extensions[i].name, name) == 0) {
 -         return extension_enabled(ctx, i);
 -      }
 -   }
 -   return GL_FALSE;
 +   if (name == 0)
 +      return GL_FALSE;
 +
 +   offset = name_to_offset(name);
 +   if (offset == 0)
 +      return GL_FALSE;
 +   base = (GLboolean *) &ctx->Extensions;
 +   return base[offset];
  }
 @@ -620,8 +749,10 @@ append(const char *a, const char *b)   * For extension names that are recognized, turn them on.  For extension
   * names that are recognized and prefixed with '-', turn them off.
   * Return a string of the unknown/leftover names.
 + *
 + * Returnd string needs to be freed.
   */
 -static const char *
 +static char *
  get_extension_override( struct gl_context *ctx )
  {
     const char *envExt = _mesa_getenv("MESA_EXTENSION_OVERRIDE");
 @@ -668,22 +799,27 @@ get_extension_override( struct gl_context *ctx )  /**
 - * Run through the default_extensions array above and set the
 - * ctx->Extensions.ARB/EXT_* flags accordingly.
 - * To be called during context initialization.
 + * \brief Initialize extension tables and enable default extensions.
 + *
 + * This should be called during context initialization.
 + * Note: Sets gl_extensions.dummy_true to true.
   */
  void
  _mesa_init_extensions( struct gl_context *ctx )
  {
     GLboolean *base = (GLboolean *) &ctx->Extensions;
 -   GLuint i;
 -
 -   for (i = 0 ; i < Elements(default_extensions) ; i++) {
 -      if (default_extensions[i].enabled &&
 -          default_extensions[i].flag_offset) {
 -         *(base + default_extensions[i].flag_offset) = GL_TRUE;
 -      }
 -   }
 +   GLboolean *sentinel = base + o(extension_sentinel);
 +   GLboolean *i;
 +   const size_t *j;
 +
 +   /* First, turn all extensions off. */
 +   for (i = base; i != sentinel; ++i)
 +      *i = GL_FALSE;
 +
 +   /* Then, selectively turn default extensions on. */
 +   ctx->Extensions.dummy_true = GL_TRUE;
 +   for (j = default_extensions; *j != 0; ++j)
 +      base[*j] = GL_TRUE;
  }
 @@ -691,256 +827,46 @@ _mesa_init_extensions( struct gl_context *ctx )   * Construct the GL_EXTENSIONS string.  Called the first time that
   * glGetString(GL_EXTENSIONS) is called.
   */
 -static GLubyte *
 -compute_extensions( struct gl_context *ctx )
 +GLubyte*
 +_mesa_make_extension_string(struct gl_context *ctx)
  {
 -   const char *extraExt = get_extension_override(ctx);
 -   GLuint extStrLen = 0;
 -   char *s;
 -   GLuint i;
 +   /* The extension string. */
 +   char *exts = 0;
 +   /* Length of extension string. */
 +   size_t length = 0;
 +   /* String of extra extensions. */
 +   char *extra_extensions = get_extension_override(ctx);
 +   GLboolean *base = (GLboolean *) &ctx->Extensions;
 +   const struct extension *i;
 -   /* first, compute length of the extension string */
 -   for (i = 0 ; i < Elements(default_extensions) ; i++) {
 -      if (extension_enabled(ctx, i)) {
 -         extStrLen += (GLuint) strlen(default_extensions[i].name) + 1;
 +   /* Compute length of the extension string. */
 +   for (i = extension_table; i->name != 0; ++i) {
 +      if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
 +	 length += strlen(i->name) + 1; /* +1 for space */
        }
     }
 +   if (extra_extensions != NULL)
 +      length += 1 + strlen(extra_extensions); /* +1 for space */
 -   if (extraExt)
 -      extStrLen += strlen(extraExt) + 1; /* +1 for space */
 -
 -   /* allocate the extension string */
 -   s = (char *) malloc(extStrLen);
 -   if (!s)
 +   exts = (char *) calloc(length + 1, sizeof(char));
 +   if (exts == NULL) {
 +      free(extra_extensions);
        return NULL;
 -
 -   /* second, build the extension string */
 -   extStrLen = 0;
 -   for (i = 0 ; i < Elements(default_extensions) ; i++) {
 -      if (extension_enabled(ctx, i)) {
 -         GLuint len = (GLuint) strlen(default_extensions[i].name);
 -         memcpy(s + extStrLen, default_extensions[i].name, len);
 -         extStrLen += len;
 -         s[extStrLen] = ' ';
 -         extStrLen++;
 -      }
 -   }
 -   ASSERT(extStrLen > 0);
 -
 -   s[extStrLen - 1] = 0; /* -1 to overwrite trailing the ' ' */
 -
 -   if (extraExt) {
 -      s = append(s, " ");
 -      s = append(s, extraExt);
 -   }
 -
 -   return (GLubyte *) s;
 -}
 -
 -static size_t
 -append_extension(GLubyte **str, const char *ext)
 -{
 -   GLubyte *s = *str;
 -   size_t len = strlen(ext);
 -
 -   if (s) {
 -      memcpy(s, ext, len);
 -      s[len++] = ' ';
 -      s[len] = '\0';
 -
 -      *str += len;
     }
 -   else {
 -      len++;
 -   }
 -
 -   return len;
 -}
 -
 -
 -static size_t
 -make_extension_string_es1(const struct gl_context *ctx, GLubyte *str)
 -{
 -   size_t len = 0;
 -
 -   /* Core additions */
 -   len += append_extension(&str, "GL_OES_byte_coordinates");
 -   len += append_extension(&str, "GL_OES_fixed_point");
 -   len += append_extension(&str, "GL_OES_single_precision");
 -   len += append_extension(&str, "GL_OES_matrix_get");
 -
 -   /* 1.1 required extensions */
 -   len += append_extension(&str, "GL_OES_read_format");
 -   len += append_extension(&str, "GL_OES_compressed_paletted_texture");
 -   len += append_extension(&str, "GL_OES_point_size_array");
 -   len += append_extension(&str, "GL_OES_point_sprite");
 -   /* 1.1 deprecated extensions */
 -   len += append_extension(&str, "GL_OES_query_matrix");
 -
 -#if FEATURE_OES_draw_texture
 -   if (ctx->Extensions.OES_draw_texture)
 -      len += append_extension(&str, "GL_OES_draw_texture");
 -#endif
 -
 -   if (ctx->Extensions.EXT_blend_equation_separate)
 -      len += append_extension(&str, "GL_OES_blend_equation_separate");
 -   if (ctx->Extensions.EXT_blend_func_separate)
 -      len += append_extension(&str, "GL_OES_blend_func_separate");
 -   if (ctx->Extensions.EXT_blend_subtract)
 -      len += append_extension(&str, "GL_OES_blend_subtract");
 -
 -   if (ctx->Extensions.EXT_stencil_wrap)
 -      len += append_extension(&str, "GL_OES_stencil_wrap");
 -
 -   if (ctx->Extensions.ARB_texture_cube_map)
 -      len += append_extension(&str, "GL_OES_texture_cube_map");
 -   if (ctx->Extensions.ARB_texture_env_crossbar)
 -      len += append_extension(&str, "GL_OES_texture_env_crossbar");
 -   if (ctx->Extensions.ARB_texture_mirrored_repeat)
 -      len += append_extension(&str, "GL_OES_texture_mirrored_repeat");
 -
 -   if (ctx->Extensions.ARB_framebuffer_object) {
 -      len += append_extension(&str, "GL_OES_framebuffer_object");
 -      len += append_extension(&str, "GL_OES_depth24");
 -      len += append_extension(&str, "GL_OES_depth32");
 -      len += append_extension(&str, "GL_OES_fbo_render_mipmap");
 -      len += append_extension(&str, "GL_OES_rgb8_rgba8");
 -      len += append_extension(&str, "GL_OES_stencil1");
 -      len += append_extension(&str, "GL_OES_stencil4");
 -      len += append_extension(&str, "GL_OES_stencil8");
 +   /* Build the extension string.*/
 +   for (i = extension_table; i->name != 0; ++i) {
 +      if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
 +         strcat(exts, i->name);
 +         strcat(exts, " ");
 +      }
     }
 -
 -   if (ctx->Extensions.EXT_vertex_array)
 -      len += append_extension(&str, "GL_OES_element_index_uint");
 -   if (ctx->Extensions.ARB_vertex_buffer_object)
 -      len += append_extension(&str, "GL_OES_mapbuffer");
 -   if (ctx->Extensions.EXT_texture_filter_anisotropic)
 -      len += append_extension(&str, "GL_EXT_texture_filter_anisotropic");
 -
 -   /* some applications check this for NPOT support */
 -   if (ctx->Extensions.ARB_texture_non_power_of_two)
 -      len += append_extension(&str, "GL_ARB_texture_non_power_of_two");
 -
 -   if (ctx->Extensions.EXT_texture_compression_s3tc)
 -      len += append_extension(&str, "GL_EXT_texture_compression_dxt1");
 -   if (ctx->Extensions.EXT_texture_lod_bias)
 -      len += append_extension(&str, "GL_EXT_texture_lod_bias");
 -   if (ctx->Extensions.EXT_blend_minmax)
 -      len += append_extension(&str, "GL_EXT_blend_minmax");
 -   if (ctx->Extensions.EXT_multi_draw_arrays)
 -      len += append_extension(&str, "GL_EXT_multi_draw_arrays");
 -
 -#if FEATURE_OES_EGL_image
 -   if (ctx->Extensions.OES_EGL_image)
 -      len += append_extension(&str, "GL_OES_EGL_image");
 -#endif
 -
 -   return len;
 -}
 -
 -
 -static GLubyte *
 -compute_extensions_es1(const struct gl_context *ctx)
 -{
 -   GLubyte *s;
 -   unsigned int len;
 -   
 -   len = make_extension_string_es1(ctx, NULL);
 -   s = malloc(len + 1);
 -   if (!s)
 -      return NULL;
 -   make_extension_string_es1(ctx, s);
 -   
 -   return s;
 -}
 -
 -static size_t
 -make_extension_string_es2(const struct gl_context *ctx, GLubyte *str)
 -{
 -   size_t len = 0;
 -
 -   if (ctx->Extensions.ARB_framebuffer_object) {
 -      len += append_extension(&str, "GL_OES_depth24");
 -      len += append_extension(&str, "GL_OES_depth32");
 -      len += append_extension(&str, "GL_OES_fbo_render_mipmap");
 -      len += append_extension(&str, "GL_OES_rgb8_rgba8");
 -      len += append_extension(&str, "GL_OES_stencil1");
 -      len += append_extension(&str, "GL_OES_stencil4");
 +   if (extra_extensions != 0) {
 +      strcat(exts, extra_extensions);
 +      free(extra_extensions);
     }
 -   if (ctx->Extensions.EXT_vertex_array)
 -      len += append_extension(&str, "GL_OES_element_index_uint");
 -   if (ctx->Extensions.ARB_vertex_buffer_object)
 -      len += append_extension(&str, "GL_OES_mapbuffer");
 -
 -#if 0
 -   /* disabled because of missing GLSL support */
 -   if (ctx->Extensions.EXT_texture3D)
 -      len += append_extension(&str, "GL_OES_texture_3D");
 -#endif
 -
 -   if (ctx->Extensions.ARB_texture_non_power_of_two)
 -      len += append_extension(&str, "GL_OES_texture_npot");
 -   if (ctx->Extensions.EXT_texture_filter_anisotropic)
 -      len += append_extension(&str, "GL_EXT_texture_filter_anisotropic");
 -
 -   len += append_extension(&str, "GL_EXT_texture_type_2_10_10_10_REV");
 -   if (ctx->Extensions.ARB_depth_texture)
 -      len += append_extension(&str, "GL_OES_depth_texture");
 -   if (ctx->Extensions.EXT_packed_depth_stencil)
 -      len += append_extension(&str, "GL_OES_packed_depth_stencil");
 -   if (ctx->Extensions.ARB_fragment_shader)
 -      len += append_extension(&str, "GL_OES_standard_derivatives");
 -
 -   if (ctx->Extensions.EXT_texture_compression_s3tc)
 -      len += append_extension(&str, "GL_EXT_texture_compression_dxt1");
 -   if (ctx->Extensions.EXT_blend_minmax)
 -      len += append_extension(&str, "GL_EXT_blend_minmax");
 -   if (ctx->Extensions.EXT_multi_draw_arrays)
 -      len += append_extension(&str, "GL_EXT_multi_draw_arrays");
 -
 -#if FEATURE_OES_EGL_image
 -   if (ctx->Extensions.OES_EGL_image)
 -      len += append_extension(&str, "GL_OES_EGL_image");
 -#endif
 -
 -   if (ctx->Extensions.EXT_texture_format_BGRA8888)
 -      len += append_extension(&str, "GL_EXT_texture_format_BGRA8888");
 -
 -   return len;
 -}
 -
 -static GLubyte *
 -compute_extensions_es2(struct gl_context *ctx)
 -{
 -   GLubyte *s;
 -   unsigned int len;
 -
 -   len = make_extension_string_es2(ctx, NULL);
 -   s = malloc(len + 1);
 -   if (!s)
 -      return NULL;
 -   make_extension_string_es2(ctx, s);
 -   
 -   return s;
 -}
 -
 -
 -GLubyte *
 -_mesa_make_extension_string(struct gl_context *ctx)
 -{
 -   switch (ctx->API) {
 -   case API_OPENGL:
 -      return compute_extensions(ctx);
 -   case API_OPENGLES2:
 -      return compute_extensions_es2(ctx);
 -   case API_OPENGLES:
 -      return compute_extensions_es1(ctx);
 -   default:
 -      assert(0);
 -      return NULL;
 -   }
 +   return (GLubyte *) exts;
  }
  /**
 @@ -949,38 +875,42 @@ _mesa_make_extension_string(struct gl_context *ctx)  GLuint
  _mesa_get_extension_count(struct gl_context *ctx)
  {
 -   GLuint i;
 +   GLboolean *base;
 +   const struct extension *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 (ctx->Extensions.Count != 0)
 +      return ctx->Extensions.Count;
 +
 +   base = (GLboolean *) &ctx->Extensions;
 +   for (i = extension_table; i->name != 0; ++i) {
 +      if (base[i->offset]) {
 +	 ctx->Extensions.Count++;
        }
     }
 -
 -   if (0)
 -      _mesa_debug(ctx, "%u of %d extensions enabled\n", ctx->Extensions.Count,
 -                  (int) Elements(default_extensions));
 -
     return ctx->Extensions.Count;
  }
 -
  /**
   * Return name of i-th enabled extension
   */
  const GLubyte *
  _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
  {
 -   GLuint i;
 +   const GLboolean *base;
 +   size_t n;
 +   const struct extension *i;
 +
 +   if (index < 0)
 +      return NULL;
 -   for (i = 0; i < Elements(default_extensions); i++) {
 -      if (extension_enabled(ctx, i)) {
 -         if (index == 0)
 -            return (const GLubyte *) default_extensions[i].name;
 -         index--;
 +   base = (GLboolean*) &ctx->Extensions;
 +   n = 0;
 +   for (i = extension_table; i->name != 0; ++i) {
 +      if (n == index && base[i->offset]) {
 +	 return (GLubyte*) i->name;
 +      } else if (base[i->offset]) {
 +	 ++n;
        }
     }
 diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 4f7a527c3..4ed2bb14e 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -999,6 +999,8 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)     case GL_RGBA12:
     case GL_RGBA16:
     case GL_RGBA16_SNORM:
 +   case GL_SRGB8_ALPHA8_EXT:
 +   case GL_SRGB8_EXT:
        return GL_RGBA;
     case GL_STENCIL_INDEX:
     case GL_STENCIL_INDEX1_EXT:
 @@ -1924,6 +1926,13 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,                       " renderbuffer %u)", renderbuffer);
  	 return;
        }
 +      else if (rb == &DummyRenderbuffer) {
 +         /* This is what NVIDIA does */
 +	 _mesa_error(ctx, GL_INVALID_VALUE,
 +		     "glFramebufferRenderbufferEXT(renderbuffer %u)",
 +                     renderbuffer);
 +	 return;
 +      }
     }
     else {
        /* remove renderbuffer attachment */
 diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index f13f6572a..81a5d5653 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -2311,8 +2311,10 @@ void GLAPIENTRY  _mesa_GetBooleanIndexedv( GLenum pname, GLuint index, GLboolean *params )
  {
     union value v;
 +   enum value_type type =
 +      find_value_indexed("glGetBooleanIndexedv", pname, index, &v);
 -   switch (find_value_indexed("glGetBooleanIndexedv", pname, index, &v)) {
 +   switch (type) {
     case TYPE_INT:
        params[0] = INT_TO_BOOLEAN(v.value_int);
        break;
 @@ -2326,7 +2328,7 @@ _mesa_GetBooleanIndexedv( GLenum pname, GLuint index, GLboolean *params )        params[0] = INT64_TO_BOOLEAN(v.value_int);
        break;
     default:
 -      assert(0);
 +      ; /* nothing - GL error was recorded */
     }
  }
 @@ -2334,8 +2336,10 @@ void GLAPIENTRY  _mesa_GetIntegerIndexedv( GLenum pname, GLuint index, GLint *params )
  {
     union value v;
 +   enum value_type type =
 +      find_value_indexed("glGetIntegerIndexedv", pname, index, &v);
 -   switch (find_value_indexed("glGetIntegerIndexedv", pname, index, &v)) {
 +   switch (type) {
     case TYPE_INT:
        params[0] = v.value_int;
        break;
 @@ -2349,7 +2353,7 @@ _mesa_GetIntegerIndexedv( GLenum pname, GLuint index, GLint *params )        params[0] = INT64_TO_INT(v.value_int);
        break;
     default:
 -      assert(0);
 +      ; /* nothing - GL error was recorded */
     }
  }
 @@ -2358,8 +2362,10 @@ void GLAPIENTRY  _mesa_GetInteger64Indexedv( GLenum pname, GLuint index, GLint64 *params )
  {
     union value v;
 +   enum value_type type =
 +      find_value_indexed("glGetIntegerIndexedv", pname, index, &v);      
 -   switch (find_value_indexed("glGetIntegerIndexedv", pname, index, &v)) {
 +   switch (type) {
     case TYPE_INT:
        params[0] = v.value_int;
        break;
 @@ -2373,7 +2379,7 @@ _mesa_GetInteger64Indexedv( GLenum pname, GLuint index, GLint64 *params )        params[0] = v.value_int;
        break;
     default:
 -      assert(0);
 +      ; /* nothing - GL error was recorded */
     }
  }
  #endif /* FEATURE_ARB_sync */
 diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index df84db93f..bcae84433 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -2655,6 +2655,8 @@ struct gl_constants  struct gl_extensions
  {
     GLboolean dummy;  /* don't remove this! */
 +   GLboolean dummy_true;  /* Set true by _mesa_init_extensions(). */
 +   GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */
     GLboolean ARB_blend_func_extended;
     GLboolean ARB_copy_buffer;
     GLboolean ARB_depth_buffer_float;
 @@ -2809,6 +2811,7 @@ struct gl_extensions     GLboolean OES_EGL_image;
     GLboolean OES_draw_texture;
     GLboolean EXT_texture_format_BGRA8888;
 +   GLboolean extension_sentinel;
     /** The extension string */
     const GLubyte *String;
     /** Number of supported extensions */
 diff --git a/mesalib/src/mesa/main/texenvprogram.c b/mesalib/src/mesa/main/texenvprogram.c index af631af14..c30fe9616 100644 --- a/mesalib/src/mesa/main/texenvprogram.c +++ b/mesalib/src/mesa/main/texenvprogram.c @@ -1467,7 +1467,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key,     p.last_tex_stage = 0;
     release_temps(ctx, &p);
 -   if (key->enabled_units) {
 +   if (key->enabled_units && key->num_draw_buffers) {
        GLboolean needbumpstage = GL_FALSE;
        /* Zeroth pass - bump map textures first */
 @@ -1560,7 +1560,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key,     _mesa_copy_instructions(p.program->Base.Instructions, instBuffer,
                             p.program->Base.NumInstructions);
 -   if (p.program->FogOption) {
 +   if (key->num_draw_buffers && p.program->FogOption) {
        _mesa_append_fog_code(ctx, p.program);
        p.program->FogOption = GL_NONE;
     }
 diff --git a/mesalib/src/mesa/main/texrender.c b/mesalib/src/mesa/main/texrender.c index 6d6e16f4a..1546f1962 100644 --- a/mesalib/src/mesa/main/texrender.c +++ b/mesalib/src/mesa/main/texrender.c @@ -595,6 +595,11 @@ update_wrapper(struct gl_context *ctx, const struct gl_renderbuffer_attachment *        trb->Base.DataType = CHAN_TYPE;
        trb->Base._BaseFormat = GL_RGBA;
        break;
 +   case MESA_FORMAT_SARGB8:
 +      trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_ARGB8888, _mesa_get_texture_dimensions(att->Texture->Target));
 +      trb->Base.DataType = CHAN_TYPE;
 +      trb->Base._BaseFormat = GL_RGBA;
 +      break;
     default:
        trb->Base.DataType = CHAN_TYPE;
        trb->Base._BaseFormat = GL_RGBA;
 diff --git a/mesalib/src/mesa/state_tracker/st_cb_queryobj.c b/mesalib/src/mesa/state_tracker/st_cb_queryobj.c index 5b9e648d0..1efcaf593 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_queryobj.c +++ b/mesalib/src/mesa/state_tracker/st_cb_queryobj.c @@ -85,6 +85,8 @@ st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q)     /* convert GL query type to Gallium query type */
     switch (q->Target) {
 +   case GL_ANY_SAMPLES_PASSED:
 +      /* fall-through */
     case GL_SAMPLES_PASSED_ARB:
        type = PIPE_QUERY_OCCLUSION_COUNTER;
        break;
 diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index 8373b8ee5..000765f2e 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -1858,9 +1858,8 @@ st_finalize_texture(struct gl_context *ctx,      * will match.
      */
     if (firstImage->pt &&
 -       stObj->pt &&
         firstImage->pt != stObj->pt &&
 -       firstImage->pt->last_level >= stObj->pt->last_level) {
 +       (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
        pipe_resource_reference(&stObj->pt, firstImage->pt);
        pipe_sampler_view_reference(&stObj->sampler_view, NULL);
     }
 diff --git a/pixman/pixman/pixman-radial-gradient.c b/pixman/pixman/pixman-radial-gradient.c index 7dfc1d04e..97c151865 100644 --- a/pixman/pixman/pixman-radial-gradient.c +++ b/pixman/pixman/pixman-radial-gradient.c @@ -96,8 +96,24 @@ radial_compute_color (double                    a,      if (a == 0)
      {
 -	return _pixman_gradient_walker_pixel (walker,
 -					      pixman_fixed_1 / 2 * c / b);
 +	double t;
 +
 +	if (b == 0)
 +	    return 0;
 +
 +	t = pixman_fixed_1 / 2 * c / b;
 +	if (repeat == PIXMAN_REPEAT_NONE)
 +	{
 +	    if (0 <= t && t <= pixman_fixed_1)
 +		return _pixman_gradient_walker_pixel (walker, t);
 +	}
 +	else
 +	{
 +	    if (t * dr > mindr)
 +		return _pixman_gradient_walker_pixel (walker, t);
 +	}
 +
 +	return 0;
      }
      det = fdot (b, a, 0, b, -c, 0);
 diff --git a/xkbcomp/configure.ac b/xkbcomp/configure.ac index 07822fe58..9ac84f682 100644 --- a/xkbcomp/configure.ac +++ b/xkbcomp/configure.ac @@ -32,7 +32,7 @@ m4_ifndef([XORG_MACROS_VERSION],  XORG_MACROS_VERSION(1.8)
  XORG_DEFAULT_OPTIONS
 -AM_CONFIG_HEADER(config.h)
 +AC_CONFIG_HEADERS([config.h])
  # If both the C file and YACC are missing, the package cannot be build.
  AC_PROG_YACC
 @@ -49,7 +49,7 @@ AC_CHECK_FUNCS([strdup strcasecmp])  PKG_CHECK_MODULES(XKBCOMP, x11 xkbfile)
  AC_ARG_WITH([xkb_config_root],
 -    [AC_HELP_STRING([--with-xkb-config-root=<paths>],
 +    [AS_HELP_STRING([--with-xkb-config-root=<paths>],
          [Set default XKB config root (default: ${datadir}/X11/xkb)])],
      [XKBCONFIGROOT="$withval"],
      [XKBCONFIGROOT='${datadir}/X11/xkb'])
 | 
