From 24a692ce832161d3b794110dd82b1508d38a0887 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Mon, 12 Sep 2011 08:58:44 +0200
Subject: git update 12 sep 2011

---
 mesalib/src/gallium/auxiliary/util/u_blitter.c     |   52 +-
 mesalib/src/glsl/ast.h                             |    2 +-
 mesalib/src/glsl/ast_to_hir.cpp                    |    6 +
 mesalib/src/glsl/builtin_stubs.cpp                 |   77 +-
 mesalib/src/glsl/glcpp/glcpp.c                     |  243 +-
 mesalib/src/glsl/ir_function_detect_recursion.cpp  |    4 +
 mesalib/src/glsl/lower_jumps.cpp                   |    1 +
 mesalib/src/glsl/opt_discard_simplification.cpp    |    1 +
 mesalib/src/glsl/opt_if_simplification.cpp         |  189 +-
 mesalib/src/glsl/standalone_scaffolding.cpp        |    1 +
 mesalib/src/mesa/drivers/dri/common/depthtmp.h     |  548 ++--
 mesalib/src/mesa/drivers/dri/common/dri_util.c     |   12 +-
 mesalib/src/mesa/drivers/dri/common/spantmp2.h     |   20 +
 mesalib/src/mesa/drivers/dri/common/utils.c        | 1532 +++++-----
 mesalib/src/mesa/drivers/dri/common/utils.h        |  221 +-
 mesalib/src/mesa/drivers/dri/swrast/swrast.c       |   19 +-
 mesalib/src/mesa/main/extensions.c                 |    8 +-
 mesalib/src/mesa/main/nvprogram.c                  |    2 +-
 mesalib/src/mesa/main/nvprogram.h                  |  238 +-
 mesalib/src/mesa/main/teximage.h                   |  571 ++--
 mesalib/src/mesa/program/ir_to_mesa.cpp            |   17 +-
 mesalib/src/mesa/program/nvvertparse.c             | 2918 ++++++++++----------
 mesalib/src/mesa/state_tracker/st_extensions.c     |   11 +-
 mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp |   33 +-
 mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c   |    2 +
 mesalib/src/mesa/swrast/s_spantemp.h               |  449 +--
 pixman/configure.ac                                |   13 +-
 pixman/pixman/pixman-arm-neon-asm.S                |  139 +-
 pixman/pixman/pixman-bits-image.c                  |   58 +-
 pixman/test/Makefile.am                            |    2 +-
 pixman/test/utils.c                                |  112 +
 pixman/test/utils.h                                |    3 +
 32 files changed, 3865 insertions(+), 3639 deletions(-)

diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c
index d8e46f07c..d69fb1a11 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.c
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c
@@ -480,10 +480,11 @@ static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
                                      unsigned level,
                                      unsigned zslice,
                                      unsigned x1, unsigned y1,
-                                     unsigned x2, unsigned y2)
+                                     unsigned x2, unsigned y2,
+				     boolean normalized)
 {
    int i;
-   float r = zslice / (float)u_minify(src->depth0, level);
+   float r = normalized ? zslice / (float)u_minify(src->depth0, level) : zslice;
 
    blitter_set_texcoords_2d(ctx, src, level, x1, y1, x2, y2);
 
@@ -491,6 +492,21 @@ static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
       ctx->vertices[i][1][2] = r; /*r*/
 }
 
+static void blitter_set_texcoords_1d_array(struct blitter_context_priv *ctx,
+                                           struct pipe_resource *src,
+                                           unsigned level,
+                                           unsigned zslice,
+                                           unsigned x1, unsigned x2)
+{
+   int i;
+   float r = zslice;
+
+   blitter_set_texcoords_2d(ctx, src, level, x1, 0, x2, 0);
+
+   for (i = 0; i < 4; i++)
+      ctx->vertices[i][1][1] = r; /*r*/
+}
+
 static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
                                        struct pipe_resource *src,
                                        unsigned level, unsigned face,
@@ -576,6 +592,10 @@ pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target)
       return TGSI_TEXTURE_3D;
    case PIPE_TEXTURE_CUBE:
       return TGSI_TEXTURE_CUBE;
+   case PIPE_TEXTURE_1D_ARRAY:
+      return TGSI_TEXTURE_1D_ARRAY;
+   case PIPE_TEXTURE_2D_ARRAY:
+      return TGSI_TEXTURE_2D_ARRAY;
    default:
       assert(0 && "unexpected texture target");
       return TGSI_TEXTURE_UNKNOWN;
@@ -861,17 +881,31 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
          break;
 
       /* Draw the quad with the generic codepath. */
-      case PIPE_TEXTURE_3D:
-      case PIPE_TEXTURE_CUBE:
+      default:
          /* Set texture coordinates. */
-         if (src->target == PIPE_TEXTURE_3D)
+         switch (src->target) {
+         case PIPE_TEXTURE_1D_ARRAY:
+            blitter_set_texcoords_1d_array(ctx, src, srclevel, srcbox->y,
+                                           srcbox->x, srcbox->x + width);
+            break;
+
+         case PIPE_TEXTURE_2D_ARRAY:
+         case PIPE_TEXTURE_3D:
             blitter_set_texcoords_3d(ctx, src, srclevel, srcbox->z,
                                      srcbox->x, srcbox->y,
-                                     srcbox->x + width, srcbox->y + height);
-         else
+                                     srcbox->x + width, srcbox->y + height,
+                                     src->target == PIPE_TEXTURE_3D);
+            break;
+
+         case PIPE_TEXTURE_CUBE:
             blitter_set_texcoords_cube(ctx, src, srclevel, srcbox->z,
                                        srcbox->x, srcbox->y,
                                        srcbox->x + width, srcbox->y + height);
+            break;
+
+         default:
+            assert(0);
+         }
 
          /* Draw. */
          blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
@@ -880,10 +914,6 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
          util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
                                  PIPE_PRIM_TRIANGLE_FAN, 4, 2);
          break;
-
-      default:
-         assert(0);
-         return;
    }
 
    blitter_restore_CSOs(ctx);
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h
index d1de22718..532347df4 100644
--- a/mesalib/src/glsl/ast.h
+++ b/mesalib/src/glsl/ast.h
@@ -372,7 +372,7 @@ struct ast_type_qualifier {
     * \note
     * This field is only valid if \c explicit_location is set.
     */
-   unsigned location;
+   int location;
 
    /**
     * Return true if and only if an interpolation qualifier is present.
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index 777f190a4..484786c5f 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -3014,6 +3014,12 @@ ast_function::hir(exec_list *instructions,
 
    const char *const name = identifier;
 
+   /* New functions are always added to the top-level IR instruction stream,
+    * so this instruction list pointer is ignored.  See also emit_function
+    * (called below).
+    */
+   (void) instructions;
+
    /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
     *
     *   "Function declarations (prototypes) cannot occur inside of functions;
diff --git a/mesalib/src/glsl/builtin_stubs.cpp b/mesalib/src/glsl/builtin_stubs.cpp
index 4c360b832..dfa5d324e 100644
--- a/mesalib/src/glsl/builtin_stubs.cpp
+++ b/mesalib/src/glsl/builtin_stubs.cpp
@@ -1,38 +1,39 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdio.h>
-#include "glsl_parser_extras.h"
-
-/* A dummy file.  When compiling prototypes, we don't care about builtins.
- * We really don't want to half-compile builtin_functions.cpp and fail, though.
- */
-void
-_mesa_glsl_release_functions(void)
-{
-}
-
-void
-_mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state)
-{
-}
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include "glsl_parser_extras.h"
+
+/* A dummy file.  When compiling prototypes, we don't care about builtins.
+ * We really don't want to half-compile builtin_functions.cpp and fail, though.
+ */
+void
+_mesa_glsl_release_functions(void)
+{
+}
+
+void
+_mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state)
+{
+   (void) state;
+}
diff --git a/mesalib/src/glsl/glcpp/glcpp.c b/mesalib/src/glsl/glcpp/glcpp.c
index 63eb061c2..e461a6502 100644
--- a/mesalib/src/glsl/glcpp/glcpp.c
+++ b/mesalib/src/glsl/glcpp/glcpp.c
@@ -1,121 +1,122 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include "glcpp.h"
-#include "main/mtypes.h"
-#include "main/shaderobj.h"
-
-extern int yydebug;
-
-void
-_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
-                       struct gl_shader *sh)
-{
-   *ptr = sh;
-}
-
-/* Read from fp until EOF and return a string of everything read.
- */
-static char *
-load_text_fp (void *ctx, FILE *fp)
-{
-#define CHUNK 4096
-	char *text = NULL;
-	size_t text_size = 0;
-	size_t total_read = 0;
-	size_t bytes;
-
-	while (1) {
-		if (total_read + CHUNK + 1 > text_size) {
-			text_size = text_size ? text_size * 2 : CHUNK + 1;
-			text = reralloc_size (ctx, text, text_size);
-			if (text == NULL) {
-				fprintf (stderr, "Out of memory\n");
-				return NULL;
-			}
-		}
-		bytes = fread (text + total_read, 1, CHUNK, fp);
-		total_read += bytes;
-
-		if (bytes < CHUNK) {
-			break;
-		}
-	}
-
-	text[total_read] = '\0';
-
-	return text;
-}
-
-static char *
-load_text_file(void *ctx, const char *filename)
-{
-	char *text;
-	FILE *fp;
-
-	if (filename == NULL || strcmp (filename, "-") == 0)
-		return load_text_fp (ctx, stdin);
-
-	fp = fopen (filename, "r");
-	if (fp == NULL) {
-		fprintf (stderr, "Failed to open file %s: %s\n",
-			 filename, strerror (errno));
-		return NULL;
-	}
-
-	text = load_text_fp (ctx, fp);
-
-	fclose(fp);
-
-	return text;
-}
-
-int
-main (int argc, char *argv[])
-{
-	char *filename = NULL;
-	void *ctx = ralloc(NULL, void*);
-	char *info_log = ralloc_strdup(ctx, "");
-	const char *shader;
-	int ret;
-
-	if (argc) {
-		filename = argv[1];
-	}
-
-	shader = load_text_file (ctx, filename);
-	if (shader == NULL)
-	   return 1;
-
-	ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL);
-
-	printf("%s", shader);
-	fprintf(stderr, "%s", info_log);
-
-	ralloc_free(ctx);
-
-	return ret;
-}
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "glcpp.h"
+#include "main/mtypes.h"
+#include "main/shaderobj.h"
+
+extern int yydebug;
+
+void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+                       struct gl_shader *sh)
+{
+   (void) ctx;
+   *ptr = sh;
+}
+
+/* Read from fp until EOF and return a string of everything read.
+ */
+static char *
+load_text_fp (void *ctx, FILE *fp)
+{
+#define CHUNK 4096
+	char *text = NULL;
+	size_t text_size = 0;
+	size_t total_read = 0;
+	size_t bytes;
+
+	while (1) {
+		if (total_read + CHUNK + 1 > text_size) {
+			text_size = text_size ? text_size * 2 : CHUNK + 1;
+			text = reralloc_size (ctx, text, text_size);
+			if (text == NULL) {
+				fprintf (stderr, "Out of memory\n");
+				return NULL;
+			}
+		}
+		bytes = fread (text + total_read, 1, CHUNK, fp);
+		total_read += bytes;
+
+		if (bytes < CHUNK) {
+			break;
+		}
+	}
+
+	text[total_read] = '\0';
+
+	return text;
+}
+
+static char *
+load_text_file(void *ctx, const char *filename)
+{
+	char *text;
+	FILE *fp;
+
+	if (filename == NULL || strcmp (filename, "-") == 0)
+		return load_text_fp (ctx, stdin);
+
+	fp = fopen (filename, "r");
+	if (fp == NULL) {
+		fprintf (stderr, "Failed to open file %s: %s\n",
+			 filename, strerror (errno));
+		return NULL;
+	}
+
+	text = load_text_fp (ctx, fp);
+
+	fclose(fp);
+
+	return text;
+}
+
+int
+main (int argc, char *argv[])
+{
+	char *filename = NULL;
+	void *ctx = ralloc(NULL, void*);
+	char *info_log = ralloc_strdup(ctx, "");
+	const char *shader;
+	int ret;
+
+	if (argc) {
+		filename = argv[1];
+	}
+
+	shader = load_text_file (ctx, filename);
+	if (shader == NULL)
+	   return 1;
+
+	ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL);
+
+	printf("%s", shader);
+	fprintf(stderr, "%s", info_log);
+
+	ralloc_free(ctx);
+
+	return ret;
+}
diff --git a/mesalib/src/glsl/ir_function_detect_recursion.cpp b/mesalib/src/glsl/ir_function_detect_recursion.cpp
index 8f805bf1b..890bc455f 100644
--- a/mesalib/src/glsl/ir_function_detect_recursion.cpp
+++ b/mesalib/src/glsl/ir_function_detect_recursion.cpp
@@ -289,6 +289,8 @@ emit_errors_unlinked(const void *key, void *data, void *closure)
    function *f = (function *) data;
    YYLTYPE loc;
 
+   (void) key;
+
    char *proto = prototype_string(f->sig->return_type,
 				  f->sig->function_name(),
 				  &f->sig->parameters);
@@ -308,6 +310,8 @@ emit_errors_linked(const void *key, void *data, void *closure)
       (struct gl_shader_program *) closure;
    function *f = (function *) data;
 
+   (void) key;
+
    char *proto = prototype_string(f->sig->return_type,
 				  f->sig->function_name(),
 				  &f->sig->parameters);
diff --git a/mesalib/src/glsl/lower_jumps.cpp b/mesalib/src/glsl/lower_jumps.cpp
index 61874990a..92813f567 100644
--- a/mesalib/src/glsl/lower_jumps.cpp
+++ b/mesalib/src/glsl/lower_jumps.cpp
@@ -438,6 +438,7 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
        * satisfied, because discard statements can't contain other
        * statements.
        */
+      (void) ir;
    }
 
    enum jump_strength get_jump_strength(ir_instruction* ir)
diff --git a/mesalib/src/glsl/opt_discard_simplification.cpp b/mesalib/src/glsl/opt_discard_simplification.cpp
index a19947ddd..ba4981bae 100644
--- a/mesalib/src/glsl/opt_discard_simplification.cpp
+++ b/mesalib/src/glsl/opt_discard_simplification.cpp
@@ -138,6 +138,7 @@ is_only_instruction(ir_discard *discard)
 ir_visitor_status
 discard_simplifier::visit_enter(ir_assignment *ir)
 {
+   (void) ir;
    return visit_continue_with_parent;
 }
 
diff --git a/mesalib/src/glsl/opt_if_simplification.cpp b/mesalib/src/glsl/opt_if_simplification.cpp
index 2d8858e49..940dd08d5 100644
--- a/mesalib/src/glsl/opt_if_simplification.cpp
+++ b/mesalib/src/glsl/opt_if_simplification.cpp
@@ -1,94 +1,95 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file opt_if_simplification.cpp
- *
- * Moves constant branches of if statements out to the surrounding
- * instruction stream.
- */
-
-#include "ir.h"
-
-class ir_if_simplification_visitor : public ir_hierarchical_visitor {
-public:
-   ir_if_simplification_visitor()
-   {
-      this->made_progress = false;
-   }
-
-   ir_visitor_status visit_leave(ir_if *);
-   ir_visitor_status visit_enter(ir_assignment *);
-
-   bool made_progress;
-};
-
-/* We only care about the top level "if" instructions, so don't
- * descend into expressions.
- */
-ir_visitor_status
-ir_if_simplification_visitor::visit_enter(ir_assignment *ir)
-{
-   return visit_continue_with_parent;
-}
-
-bool
-do_if_simplification(exec_list *instructions)
-{
-   ir_if_simplification_visitor v;
-
-   v.run(instructions);
-   return v.made_progress;
-}
-
-
-ir_visitor_status
-ir_if_simplification_visitor::visit_leave(ir_if *ir)
-{
-   /* FINISHME: Ideally there would be a way to note that the condition results
-    * FINISHME: in a constant before processing both of the other subtrees.
-    * FINISHME: This can probably be done with some flags, but it would take
-    * FINISHME: some work to get right.
-    */
-   ir_constant *condition_constant = ir->condition->constant_expression_value();
-   if (condition_constant) {
-      /* Move the contents of the one branch of the conditional
-       * that matters out.
-       */
-      if (condition_constant->value.b[0]) {
-	 foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
-	    ir_instruction *then_ir = (ir_instruction *)then_iter.get();
-	    ir->insert_before(then_ir);
-	 }
-      } else {
-	 foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
-	    ir_instruction *else_ir = (ir_instruction *)else_iter.get();
-	    ir->insert_before(else_ir);
-	 }
-      }
-      ir->remove();
-      this->made_progress = true;
-   }
-
-   return visit_continue;
-}
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file opt_if_simplification.cpp
+ *
+ * Moves constant branches of if statements out to the surrounding
+ * instruction stream.
+ */
+
+#include "ir.h"
+
+class ir_if_simplification_visitor : public ir_hierarchical_visitor {
+public:
+   ir_if_simplification_visitor()
+   {
+      this->made_progress = false;
+   }
+
+   ir_visitor_status visit_leave(ir_if *);
+   ir_visitor_status visit_enter(ir_assignment *);
+
+   bool made_progress;
+};
+
+/* We only care about the top level "if" instructions, so don't
+ * descend into expressions.
+ */
+ir_visitor_status
+ir_if_simplification_visitor::visit_enter(ir_assignment *ir)
+{
+   (void) ir;
+   return visit_continue_with_parent;
+}
+
+bool
+do_if_simplification(exec_list *instructions)
+{
+   ir_if_simplification_visitor v;
+
+   v.run(instructions);
+   return v.made_progress;
+}
+
+
+ir_visitor_status
+ir_if_simplification_visitor::visit_leave(ir_if *ir)
+{
+   /* FINISHME: Ideally there would be a way to note that the condition results
+    * FINISHME: in a constant before processing both of the other subtrees.
+    * FINISHME: This can probably be done with some flags, but it would take
+    * FINISHME: some work to get right.
+    */
+   ir_constant *condition_constant = ir->condition->constant_expression_value();
+   if (condition_constant) {
+      /* Move the contents of the one branch of the conditional
+       * that matters out.
+       */
+      if (condition_constant->value.b[0]) {
+	 foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
+	    ir_instruction *then_ir = (ir_instruction *)then_iter.get();
+	    ir->insert_before(then_ir);
+	 }
+      } else {
+	 foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
+	    ir_instruction *else_ir = (ir_instruction *)else_iter.get();
+	    ir->insert_before(else_ir);
+	 }
+      }
+      ir->remove();
+      this->made_progress = true;
+   }
+
+   return visit_continue;
+}
diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp
index bbd7bb913..72aa1e428 100644
--- a/mesalib/src/glsl/standalone_scaffolding.cpp
+++ b/mesalib/src/glsl/standalone_scaffolding.cpp
@@ -37,6 +37,7 @@ void
 _mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
                        struct gl_shader *sh)
 {
+   (void) ctx;
    *ptr = sh;
 }
 
diff --git a/mesalib/src/mesa/drivers/dri/common/depthtmp.h b/mesalib/src/mesa/drivers/dri/common/depthtmp.h
index 8e751d7b2..c6e2bb75c 100644
--- a/mesalib/src/mesa/drivers/dri/common/depthtmp.h
+++ b/mesalib/src/mesa/drivers/dri/common/depthtmp.h
@@ -1,270 +1,278 @@
-
-/*
- * Notes:
- * 1. These functions plug into the gl_renderbuffer structure.
- * 2. The 'values' parameter always points to GLuint values, regardless of
- *    the actual Z buffer depth.
- */
-
-
-#include "spantmp_common.h"
-
-#ifndef DBG
-#define DBG 0
-#endif
-
-#ifndef HAVE_HW_DEPTH_SPANS
-#define HAVE_HW_DEPTH_SPANS 0
-#endif
-
-#ifndef HAVE_HW_DEPTH_PIXELS
-#define HAVE_HW_DEPTH_PIXELS 0
-#endif
-
-static void TAG(WriteDepthSpan)( struct gl_context *ctx,
-                                 struct gl_renderbuffer *rb,
-                                 GLuint n, GLint x, GLint y,
-				 const void *values,
-				 const GLubyte mask[] )
-{
-   HW_WRITE_LOCK()
-      {
-         const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
-	 GLint x1;
-	 GLint n1;
-	 LOCAL_DEPTH_VARS;
-
-	 y = Y_FLIP( y );
-
-#if HAVE_HW_DEPTH_SPANS
-	 (void) x1; (void) n1;
-
-	 if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n",
-			     (int)n, (int)x );
-
-	 WRITE_DEPTH_SPAN();
-#else
-	 HW_CLIPLOOP()
-	    {
-	       GLint i = 0;
-	       CLIPSPAN( x, y, n, x1, n1, i );
-
-	       if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d) (mask %p)\n",
-				   (int)i, (int)n1, (int)x1, mask );
-
-	       if ( mask ) {
-		  for ( ; n1>0 ; i++, x1++, n1-- ) {
-		     if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] );
-		  }
-	       } else {
-		  for ( ; n1>0 ; i++, x1++, n1-- ) {
-		     WRITE_DEPTH( x1, y, depth[i] );
-		  }
-	       }
-	    }
-	 HW_ENDCLIPLOOP();
-#endif
-      }
-   HW_WRITE_UNLOCK();
-}
-
-
-#if HAVE_HW_DEPTH_SPANS
-/* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */
-static void
-TAG(WriteMonoDepthSpan)( struct gl_context *ctx, struct gl_renderbuffer *rb,
-                         GLuint n, GLint x, GLint y,
-                         const void *value, const GLubyte mask[] )
-{
-   const GLuint depthVal = *((GLuint *) value);
-   GLuint depths[MAX_WIDTH];
-   GLuint i;
-   for (i = 0; i < n; i++)
-      depths[i] = depthVal;
-   TAG(WriteDepthSpan)(ctx, rb, n, x, y, depths, mask);
-}
-#else
-static void TAG(WriteMonoDepthSpan)( struct gl_context *ctx,
-                                     struct gl_renderbuffer *rb,
-                                     GLuint n, GLint x, GLint y,
-                                     const void *value,
-                                     const GLubyte mask[] )
-{
-   HW_WRITE_LOCK()
-      {
-         const GLuint depth = *((GLuint *) value);
-	 GLint x1;
-	 GLint n1;
-	 LOCAL_DEPTH_VARS;
-
-	 y = Y_FLIP( y );
-
-	 HW_CLIPLOOP()
-	    {
-	       GLint i = 0;
-	       CLIPSPAN( x, y, n, x1, n1, i );
-
-	       if ( DBG ) fprintf( stderr, "%s %d..%d (x1 %d) = %u\n",
-				   __FUNCTION__, (int)i, (int)n1, (int)x1, (GLuint)depth );
-
-	       if ( mask ) {
-		  for ( ; n1>0 ; i++, x1++, n1-- ) {
-		     if ( mask[i] ) WRITE_DEPTH( x1, y, depth );
-		  }
-	       } else {
-		  for ( ; n1>0 ; x1++, n1-- ) {
-		     WRITE_DEPTH( x1, y, depth );
-		  }
-	       }
-	    }
-	 HW_ENDCLIPLOOP();
-      }
-   HW_WRITE_UNLOCK();
-}
-#endif
-
-
-static void TAG(WriteDepthPixels)( struct gl_context *ctx,
-                                   struct gl_renderbuffer *rb,
-				   GLuint n,
-				   const GLint x[],
-				   const GLint y[],
-				   const void *values,
-				   const GLubyte mask[] )
-{
-   HW_WRITE_LOCK()
-      {
-         const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
-	 GLuint i;
-	 LOCAL_DEPTH_VARS;
-
-	 if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" );
-
-#if HAVE_HW_DEPTH_PIXELS
-	 (void) i;
-
-	 WRITE_DEPTH_PIXELS();
-#else
-	 HW_CLIPLOOP()
-	    {
-	       if ( mask ) {
-		  for ( i = 0 ; i < n ; i++ ) {
-		     if ( mask[i] ) {
-			const int fy = Y_FLIP( y[i] );
-			if ( CLIPPIXEL( x[i], fy ) )
-			   WRITE_DEPTH( x[i], fy, depth[i] );
-		     }
-		  }
-	       }
-	       else {
-		  for ( i = 0 ; i < n ; i++ ) {
-		     const int fy = Y_FLIP( y[i] );
-		     if ( CLIPPIXEL( x[i], fy ) )
-			WRITE_DEPTH( x[i], fy, depth[i] );
-		  }
-	       }
-	    }
-	 HW_ENDCLIPLOOP();
-#endif
-      }
-   HW_WRITE_UNLOCK();
-}
-
-
-/* Read depth spans and pixels
- */
-static void TAG(ReadDepthSpan)( struct gl_context *ctx,
-                                struct gl_renderbuffer *rb,
-				GLuint n, GLint x, GLint y,
-				void *values )
-{
-   HW_READ_LOCK()
-      {
-         VALUE_TYPE *depth = (VALUE_TYPE *) values;
-	 GLint x1, n1;
-	 LOCAL_DEPTH_VARS;
-
-	 y = Y_FLIP( y );
-
-	 if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" );
-
-#if HAVE_HW_DEPTH_SPANS
-	 (void) x1; (void) n1;
-
-	 READ_DEPTH_SPAN();
-#else
-	 HW_CLIPLOOP()
-	    {
-	       GLint i = 0;
-	       CLIPSPAN( x, y, n, x1, n1, i );
-	       for ( ; n1>0 ; i++, n1-- ) {
-		  READ_DEPTH( depth[i], x+i, y );
-	       }
-	    }
-	 HW_ENDCLIPLOOP();
-#endif
-      }
-   HW_READ_UNLOCK();
-}
-
-static void TAG(ReadDepthPixels)( struct gl_context *ctx,
-                                  struct gl_renderbuffer *rb,
-                                  GLuint n,
-				  const GLint x[], const GLint y[],
-				  void *values )
-{
-   HW_READ_LOCK()
-      {
-         VALUE_TYPE *depth = (VALUE_TYPE *) values;
-	 GLuint i;
-	 LOCAL_DEPTH_VARS;
-
-	 if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" );
-
-#if HAVE_HW_DEPTH_PIXELS
-	 (void) i;
-
-	 READ_DEPTH_PIXELS();
-#else
-	 HW_CLIPLOOP()
-	    {
-	       for ( i = 0 ; i < n ;i++ ) {
-		  int fy = Y_FLIP( y[i] );
-		  if ( CLIPPIXEL( x[i], fy ) )
-		     READ_DEPTH( depth[i], x[i], fy );
-	       }
-	    }
-	 HW_ENDCLIPLOOP();
-#endif
-      }
-   HW_READ_UNLOCK();
-}
-
-
-/**
- * Initialize the given renderbuffer's span routines to point to
- * the depth/z functions we generated above.
- */
-static void TAG(InitDepthPointers)(struct gl_renderbuffer *rb)
-{
-   rb->GetRow = TAG(ReadDepthSpan);
-   rb->GetValues = TAG(ReadDepthPixels);
-   rb->PutRow = TAG(WriteDepthSpan);
-   rb->PutRowRGB = NULL;
-   rb->PutMonoRow = TAG(WriteMonoDepthSpan);
-   rb->PutValues = TAG(WriteDepthPixels);
-   rb->PutMonoValues = NULL;
-}
-
-
-#if HAVE_HW_DEPTH_SPANS
-#undef WRITE_DEPTH_SPAN
-#undef WRITE_DEPTH_PIXELS
-#undef READ_DEPTH_SPAN
-#undef READ_DEPTH_PIXELS
-#else
-#undef WRITE_DEPTH
-#undef READ_DEPTH
-#endif
-#undef TAG
-#undef VALUE_TYPE
+
+/*
+ * Notes:
+ * 1. These functions plug into the gl_renderbuffer structure.
+ * 2. The 'values' parameter always points to GLuint values, regardless of
+ *    the actual Z buffer depth.
+ */
+
+
+#include "spantmp_common.h"
+
+#ifndef DBG
+#define DBG 0
+#endif
+
+#ifndef HAVE_HW_DEPTH_SPANS
+#define HAVE_HW_DEPTH_SPANS 0
+#endif
+
+#ifndef HAVE_HW_DEPTH_PIXELS
+#define HAVE_HW_DEPTH_PIXELS 0
+#endif
+
+static void TAG(WriteDepthSpan)( struct gl_context *ctx,
+                                 struct gl_renderbuffer *rb,
+                                 GLuint n, GLint x, GLint y,
+				 const void *values,
+				 const GLubyte mask[] )
+{
+   HW_WRITE_LOCK()
+      {
+         const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
+	 GLint x1;
+	 GLint n1;
+	 LOCAL_DEPTH_VARS;
+
+	 y = Y_FLIP( y );
+
+#if HAVE_HW_DEPTH_SPANS
+	 (void) x1; (void) n1;
+
+	 if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n",
+			     (int)n, (int)x );
+
+	 WRITE_DEPTH_SPAN();
+#else
+	 HW_CLIPLOOP()
+	    {
+	       GLint i = 0;
+	       CLIPSPAN( x, y, n, x1, n1, i );
+
+	       if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d) (mask %p)\n",
+				   (int)i, (int)n1, (int)x1, mask );
+
+	       if ( mask ) {
+		  for ( ; n1>0 ; i++, x1++, n1-- ) {
+		     if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] );
+		  }
+	       } else {
+		  for ( ; n1>0 ; i++, x1++, n1-- ) {
+		     WRITE_DEPTH( x1, y, depth[i] );
+		  }
+	       }
+	    }
+	 HW_ENDCLIPLOOP();
+#endif
+      }
+   HW_WRITE_UNLOCK();
+
+   (void) ctx;
+}
+
+
+#if HAVE_HW_DEPTH_SPANS
+/* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */
+static void
+TAG(WriteMonoDepthSpan)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+                         GLuint n, GLint x, GLint y,
+                         const void *value, const GLubyte mask[] )
+{
+   const GLuint depthVal = *((GLuint *) value);
+   GLuint depths[MAX_WIDTH];
+   GLuint i;
+   for (i = 0; i < n; i++)
+      depths[i] = depthVal;
+   TAG(WriteDepthSpan)(ctx, rb, n, x, y, depths, mask);
+}
+#else
+static void TAG(WriteMonoDepthSpan)( struct gl_context *ctx,
+                                     struct gl_renderbuffer *rb,
+                                     GLuint n, GLint x, GLint y,
+                                     const void *value,
+                                     const GLubyte mask[] )
+{
+   HW_WRITE_LOCK()
+      {
+         const GLuint depth = *((GLuint *) value);
+	 GLint x1;
+	 GLint n1;
+	 LOCAL_DEPTH_VARS;
+
+	 y = Y_FLIP( y );
+
+	 HW_CLIPLOOP()
+	    {
+	       GLint i = 0;
+	       CLIPSPAN( x, y, n, x1, n1, i );
+
+	       if ( DBG ) fprintf( stderr, "%s %d..%d (x1 %d) = %u\n",
+				   __FUNCTION__, (int)i, (int)n1, (int)x1, (GLuint)depth );
+
+	       if ( mask ) {
+		  for ( ; n1>0 ; i++, x1++, n1-- ) {
+		     if ( mask[i] ) WRITE_DEPTH( x1, y, depth );
+		  }
+	       } else {
+		  for ( ; n1>0 ; x1++, n1-- ) {
+		     WRITE_DEPTH( x1, y, depth );
+		  }
+	       }
+	    }
+	 HW_ENDCLIPLOOP();
+      }
+   HW_WRITE_UNLOCK();
+
+   (void) ctx;
+}
+#endif
+
+
+static void TAG(WriteDepthPixels)( struct gl_context *ctx,
+                                   struct gl_renderbuffer *rb,
+				   GLuint n,
+				   const GLint x[],
+				   const GLint y[],
+				   const void *values,
+				   const GLubyte mask[] )
+{
+   HW_WRITE_LOCK()
+      {
+         const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
+	 GLuint i;
+	 LOCAL_DEPTH_VARS;
+
+	 if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" );
+
+#if HAVE_HW_DEPTH_PIXELS
+	 (void) i;
+
+	 WRITE_DEPTH_PIXELS();
+#else
+	 HW_CLIPLOOP()
+	    {
+	       if ( mask ) {
+		  for ( i = 0 ; i < n ; i++ ) {
+		     if ( mask[i] ) {
+			const int fy = Y_FLIP( y[i] );
+			if ( CLIPPIXEL( x[i], fy ) )
+			   WRITE_DEPTH( x[i], fy, depth[i] );
+		     }
+		  }
+	       }
+	       else {
+		  for ( i = 0 ; i < n ; i++ ) {
+		     const int fy = Y_FLIP( y[i] );
+		     if ( CLIPPIXEL( x[i], fy ) )
+			WRITE_DEPTH( x[i], fy, depth[i] );
+		  }
+	       }
+	    }
+	 HW_ENDCLIPLOOP();
+#endif
+      }
+   HW_WRITE_UNLOCK();
+
+   (void) ctx;
+}
+
+
+/* Read depth spans and pixels
+ */
+static void TAG(ReadDepthSpan)( struct gl_context *ctx,
+                                struct gl_renderbuffer *rb,
+				GLuint n, GLint x, GLint y,
+				void *values )
+{
+   HW_READ_LOCK()
+      {
+         VALUE_TYPE *depth = (VALUE_TYPE *) values;
+	 GLint x1, n1;
+	 LOCAL_DEPTH_VARS;
+
+	 y = Y_FLIP( y );
+
+	 if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" );
+
+#if HAVE_HW_DEPTH_SPANS
+	 (void) x1; (void) n1;
+
+	 READ_DEPTH_SPAN();
+#else
+	 HW_CLIPLOOP()
+	    {
+	       GLint i = 0;
+	       CLIPSPAN( x, y, n, x1, n1, i );
+	       for ( ; n1>0 ; i++, n1-- ) {
+		  READ_DEPTH( depth[i], x+i, y );
+	       }
+	    }
+	 HW_ENDCLIPLOOP();
+#endif
+      }
+   HW_READ_UNLOCK();
+}
+
+static void TAG(ReadDepthPixels)( struct gl_context *ctx,
+                                  struct gl_renderbuffer *rb,
+                                  GLuint n,
+				  const GLint x[], const GLint y[],
+				  void *values )
+{
+   HW_READ_LOCK()
+      {
+         VALUE_TYPE *depth = (VALUE_TYPE *) values;
+	 GLuint i;
+	 LOCAL_DEPTH_VARS;
+
+	 if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" );
+
+#if HAVE_HW_DEPTH_PIXELS
+	 (void) i;
+
+	 READ_DEPTH_PIXELS();
+#else
+	 HW_CLIPLOOP()
+	    {
+	       for ( i = 0 ; i < n ;i++ ) {
+		  int fy = Y_FLIP( y[i] );
+		  if ( CLIPPIXEL( x[i], fy ) )
+		     READ_DEPTH( depth[i], x[i], fy );
+	       }
+	    }
+	 HW_ENDCLIPLOOP();
+#endif
+      }
+   HW_READ_UNLOCK();
+
+   (void) ctx;
+}
+
+
+/**
+ * Initialize the given renderbuffer's span routines to point to
+ * the depth/z functions we generated above.
+ */
+static void TAG(InitDepthPointers)(struct gl_renderbuffer *rb)
+{
+   rb->GetRow = TAG(ReadDepthSpan);
+   rb->GetValues = TAG(ReadDepthPixels);
+   rb->PutRow = TAG(WriteDepthSpan);
+   rb->PutRowRGB = NULL;
+   rb->PutMonoRow = TAG(WriteMonoDepthSpan);
+   rb->PutValues = TAG(WriteDepthPixels);
+   rb->PutMonoValues = NULL;
+}
+
+
+#if HAVE_HW_DEPTH_SPANS
+#undef WRITE_DEPTH_SPAN
+#undef WRITE_DEPTH_PIXELS
+#undef READ_DEPTH_SPAN
+#undef READ_DEPTH_PIXELS
+#else
+#undef WRITE_DEPTH
+#undef READ_DEPTH
+#endif
+#undef TAG
+#undef VALUE_TYPE
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c
index 82638fa72..6d6401934 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.c
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c
@@ -418,6 +418,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
      * supported either.
      */
     (void) attrs;
+    (void) renderType;
 
     pdp = malloc(sizeof *pdp);
     if (!pdp) {
@@ -594,8 +595,10 @@ driDestroyContext(__DRIcontext *pcp)
 /**
  * Create the per-drawable private driver information.
  * 
- * \param render_type   Type of rendering target.  \c GLX_RGBA is the only
+ * \param render_type   Type of rendering target.  \c GLX_RGBA_TYPE is the only
  *                      type likely to ever be supported for direct-rendering.
+ *                      However, \c GLX_RGBA_FLOAT_TYPE_ARB may eventually be
+ *                      supported by some drivers.
  * \param shared        Context with which to share textures, etc. or NULL
  *
  * \returns An opaque pointer to the per-context private information on
@@ -616,6 +619,8 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
     __DRIcontext *pcp;
     void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
 
+    (void) render_type;
+
     pcp = malloc(sizeof *pcp);
     if (!pcp)
 	return NULL;
@@ -700,6 +705,9 @@ dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
 static int
 driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
 {
+    (void) dest;
+    (void) src;
+    (void) mask;
     return GL_FALSE;
 }
 
@@ -806,6 +814,8 @@ driCreateNewScreen(int scrn,
     static const __DRIextension *emptyExtensionList[] = { NULL };
     __DRIscreen *psp;
 
+    (void) loaderPrivate;
+
     if (driDriverAPI.InitScreen == NULL)
 	return NULL;
 
diff --git a/mesalib/src/mesa/drivers/dri/common/spantmp2.h b/mesalib/src/mesa/drivers/dri/common/spantmp2.h
index abd79562f..83cfbb164 100644
--- a/mesalib/src/mesa/drivers/dri/common/spantmp2.h
+++ b/mesalib/src/mesa/drivers/dri/common/spantmp2.h
@@ -465,6 +465,8 @@ static void TAG(WriteRGBASpan)( struct gl_context *ctx,
 				GLuint n, GLint x, GLint y,
 				const void *values, const GLubyte mask[] )
 {
+   (void) ctx;
+
    HW_WRITE_LOCK()
       {
          const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
@@ -508,6 +510,8 @@ static void TAG(WriteRGBSpan)( struct gl_context *ctx,
 			       GLuint n, GLint x, GLint y,
 			       const void *values, const GLubyte mask[] )
 {
+   (void) ctx;
+
    HW_WRITE_LOCK()
       {
          const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
@@ -547,6 +551,8 @@ static void TAG(WriteRGBAPixels)( struct gl_context *ctx,
                                   GLuint n, const GLint x[], const GLint y[],
                                   const void *values, const GLubyte mask[] )
 {
+   (void) ctx;
+
    HW_WRITE_LOCK()
       {
          const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
@@ -593,6 +599,8 @@ static void TAG(WriteMonoRGBASpan)( struct gl_context *ctx,
 				    GLuint n, GLint x, GLint y, 
 				    const void *value, const GLubyte mask[] )
 {
+   (void) ctx;
+
    HW_WRITE_LOCK()
       {
          const GLubyte *color = (const GLubyte *) value;
@@ -634,6 +642,8 @@ static void TAG(WriteMonoRGBAPixels)( struct gl_context *ctx,
 				      const void *value,
 				      const GLubyte mask[] ) 
 {
+   (void) ctx;
+
    HW_WRITE_LOCK()
       {
          const GLubyte *color = (const GLubyte *) value;
@@ -673,6 +683,8 @@ static void TAG(ReadRGBASpan)( struct gl_context *ctx,
                                struct gl_renderbuffer *rb,
 			       GLuint n, GLint x, GLint y, void *values)
 {
+   (void) ctx;
+
    HW_READ_LOCK()
       {
          GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
@@ -713,6 +725,8 @@ static void TAG2(ReadRGBASpan,_MMX)( struct gl_context *ctx,
    __asm__ __volatile__( "emms" );
 #endif
 
+   (void) ctx;
+
    HW_READ_LOCK()
      {
         GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
@@ -757,6 +771,8 @@ static void TAG2(ReadRGBASpan,_SSE2)( struct gl_context *ctx,
                                       GLuint n, GLint x, GLint y,
                                       void *values)
 {
+   (void) ctx;
+
    HW_READ_LOCK()
      {
         GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
@@ -799,6 +815,8 @@ static void TAG2(ReadRGBASpan,_SSE)( struct gl_context *ctx,
    __asm__ __volatile__( "emms" );
 #endif
 
+   (void) ctx;
+
    HW_READ_LOCK()
      {
         GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
@@ -834,6 +852,8 @@ static void TAG(ReadRGBAPixels)( struct gl_context *ctx,
 				 GLuint n, const GLint x[], const GLint y[],
 				 void *values )
 {
+   (void) ctx;
+
    HW_READ_LOCK()
       {
          GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c
index 539296d1a..54156d34a 100644
--- a/mesalib/src/mesa/drivers/dri/common/utils.c
+++ b/mesalib/src/mesa/drivers/dri/common/utils.c
@@ -1,823 +1,709 @@
-/*
- * (C) Copyright IBM Corporation 2002, 2004
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file utils.c
- * Utility functions for DRI drivers.
- *
- * \author Ian Romanick <idr@us.ibm.com>
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include "main/mtypes.h"
-#include "main/cpuinfo.h"
-#include "main/extensions.h"
-#include "utils.h"
-
-
-/**
- * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
- * is set. 
- * 
- * Is called from the drivers.
- * 
- * \param f \c printf like format string.
- */
-void
-__driUtilMessage(const char *f, ...)
-{
-    va_list args;
-
-    if (getenv("LIBGL_DEBUG")) {
-        fprintf(stderr, "libGL: ");
-        va_start(args, f);
-        vfprintf(stderr, f, args);
-        va_end(args);
-        fprintf(stderr, "\n");
-    }
-}
-
-
-unsigned
-driParseDebugString( const char * debug, 
-		     const struct dri_debug_control * control  )
-{
-   unsigned   flag;
-
-
-   flag = 0;
-   if ( debug != NULL ) {
-      while( control->string != NULL ) {
-	 if ( !strcmp( debug, "all" ) ||
-	      strstr( debug, control->string ) != NULL ) {
-	    flag |= control->flag;
-	 }
-
-	 control++;
-      }
-   }
-
-   return flag;
-}
-
-
-
-/**
- * Create the \c GL_RENDERER string for DRI drivers.
- * 
- * Almost all DRI drivers use a \c GL_RENDERER string of the form:
- *
- *    "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>"
- *
- * Using the supplied chip name, driver data, and AGP speed, this function
- * creates the string.
- * 
- * \param buffer         Buffer to hold the \c GL_RENDERER string.
- * \param hardware_name  Name of the hardware.
- * \param agp_mode       AGP mode (speed).
- * 
- * \returns
- * The length of the string stored in \c buffer.  This does \b not include
- * the terminating \c NUL character.
- */
-unsigned
-driGetRendererString( char * buffer, const char * hardware_name,
-		      GLuint agp_mode )
-{
-   unsigned offset;
-   char *cpu;
-
-   offset = sprintf( buffer, "Mesa DRI %s", hardware_name );
-
-   /* Append any AGP-specific information.
-    */
-   switch ( agp_mode ) {
-   case 1:
-   case 2:
-   case 4:
-   case 8:
-      offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode );
-      break;
-	
-   default:
-      break;
-   }
-
-   /* Append any CPU-specific information.
-    */
-   cpu = _mesa_get_cpu_string();
-   if (cpu) {
-      offset += sprintf(buffer + offset, " %s", cpu);
-      free(cpu);
-   }
-
-   return offset;
-}
-
-
-
-
-#define need_GL_ARB_copy_buffer
-#define need_GL_ARB_draw_buffers
-#define need_GL_ARB_multisample
-#define need_GL_ARB_texture_compression
-#define need_GL_ARB_transpose_matrix
-#define need_GL_ARB_vertex_buffer_object
-#define need_GL_ARB_window_pos
-#define need_GL_EXT_compiled_vertex_array
-#define need_GL_EXT_multi_draw_arrays
-#define need_GL_EXT_polygon_offset
-#define need_GL_EXT_texture_object
-#define need_GL_EXT_vertex_array
-#define need_GL_IBM_multimode_draw_arrays
-#define need_GL_MESA_window_pos
-
-/* These are needed in *all* drivers because Mesa internally implements
- * certain functionality in terms of functions provided by these extensions.
- * For example, glBlendFunc is implemented by calling glBlendFuncSeparateEXT.
- */
-#define need_GL_EXT_blend_func_separate
-#define need_GL_NV_vertex_program
-
-#include "main/remap_helper.h"
-
-static const struct dri_extension all_mesa_extensions[] = {
-   { "GL_ARB_copy_buffer",           GL_ARB_copy_buffer_functions },
-   { "GL_ARB_draw_buffers",          GL_ARB_draw_buffers_functions },
-   { "GL_ARB_multisample",           GL_ARB_multisample_functions },
-   { "GL_ARB_texture_compression",   GL_ARB_texture_compression_functions },
-   { "GL_ARB_transpose_matrix",      GL_ARB_transpose_matrix_functions },
-   { "GL_ARB_vertex_buffer_object",  GL_ARB_vertex_buffer_object_functions},
-   { "GL_ARB_window_pos",            GL_ARB_window_pos_functions },
-   { "GL_EXT_blend_func_separate",   GL_EXT_blend_func_separate_functions },
-   { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions },
-   { "GL_EXT_multi_draw_arrays",     GL_EXT_multi_draw_arrays_functions },
-   { "GL_EXT_polygon_offset",        GL_EXT_polygon_offset_functions },
-   { "GL_EXT_texture_object",        GL_EXT_texture_object_functions },
-   { "GL_EXT_vertex_array",          GL_EXT_vertex_array_functions },
-   { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions },
-   { "GL_MESA_window_pos",           GL_MESA_window_pos_functions },
-   { "GL_NV_vertex_program",         GL_NV_vertex_program_functions },
-   { NULL,                           NULL }
-};
-
-
-/**
- * Enable and map extensions supported by the driver.
- * 
- * When ctx is NULL, extensions are not enabled, but their functions
- * are still mapped.  When extensions_to_enable is NULL, all static
- * functions known to mesa core are mapped.
- *
- * \bug
- * ARB_imaging isn't handled properly.  In Mesa, enabling ARB_imaging also
- * enables all the sub-extensions that are folded into it.  This means that
- * we need to add entry-points (via \c driInitSingleExtension) for those
- * new functions here.
- */
-void driInitExtensions( struct gl_context * ctx,
-			const struct dri_extension * extensions_to_enable,
-			GLboolean enable_imaging )
-{
-   static int first_time = 1;
-   unsigned   i;
-
-   if ( first_time ) {
-      first_time = 0;
-      driInitExtensions( NULL, all_mesa_extensions, GL_FALSE );
-   }
-
-   if ( (ctx != NULL) && enable_imaging ) {
-      _mesa_enable_imaging_extensions( ctx );
-   }
-
-   /* The caller is too lazy to list any extension */
-   if ( extensions_to_enable == NULL ) {
-      /* Map the static functions.  Together with those mapped by remap
-       * table, this should cover everything mesa core knows.
-       */
-      _mesa_map_static_functions();
-      return;
-   }
-
-   for ( i = 0 ; extensions_to_enable[i].name != NULL ; i++ ) {
-       driInitSingleExtension( ctx, & extensions_to_enable[i] );
-   }
-}
-
-
-
-
-/**
- * Enable and map functions for a single extension
- * 
- * \param ctx  Context where extension is to be enabled.
- * \param ext  Extension that is to be enabled.
- * 
- * \sa driInitExtensions, _mesa_enable_extension, _mesa_map_function_array
- */
-void driInitSingleExtension( struct gl_context * ctx,
-			     const struct dri_extension * ext )
-{
-    if ( ext->functions != NULL ) {
-       _mesa_map_function_array(ext->functions);
-    }
-
-    if ( ctx != NULL ) {
-	_mesa_enable_extension( ctx, ext->name );
-    }
-}
-
-
-/**
- * Utility function used by drivers to test the verions of other components.
- *
- * \param driver_name  Name of the driver.  Used in error messages.
- * \param driActual    Actual DRI version supplied __driCreateNewScreen.
- * \param driExpected  Minimum DRI version required by the driver.
- * \param ddxActual    Actual DDX version supplied __driCreateNewScreen.
- * \param ddxExpected  Minimum DDX minor and range of DDX major version required by the driver.
- * \param drmActual    Actual DRM version supplied __driCreateNewScreen.
- * \param drmExpected  Minimum DRM version required by the driver.
- * 
- * \returns \c GL_TRUE if all version requirements are met.  Otherwise,
- *          \c GL_FALSE is returned.
- * 
- * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2
- *
- * \todo
- * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
- * function and \c driCheckDriDdxDrmVersions2 should be renamed.
- */
-GLboolean
-driCheckDriDdxDrmVersions3(const char * driver_name,
-			   const __DRIversion * driActual,
-			   const __DRIversion * driExpected,
-			   const __DRIversion * ddxActual,
-			   const __DRIutilversion2 * ddxExpected,
-			   const __DRIversion * drmActual,
-			   const __DRIversion * drmExpected)
-{
-   static const char format[] = "%s DRI driver expected %s version %d.%d.x "
-       "but got version %d.%d.%d\n";
-   static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x "
-       "but got version %d.%d.%d\n";
-
-
-   /* Check the DRI version */
-   if ( (driActual->major != driExpected->major)
-	|| (driActual->minor < driExpected->minor) ) {
-      fprintf(stderr, format, driver_name, "DRI",
-		       driExpected->major, driExpected->minor,
-		       driActual->major, driActual->minor, driActual->patch);
-      return GL_FALSE;
-   }
-
-   /* Check that the DDX driver version is compatible */
-   if ( (ddxActual->major < ddxExpected->major_min)
-	|| (ddxActual->major > ddxExpected->major_max)
-	|| (ddxActual->minor < ddxExpected->minor) ) {
-      fprintf(stderr, format2, driver_name, "DDX",
-		       ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor,
-		       ddxActual->major, ddxActual->minor, ddxActual->patch);
-      return GL_FALSE;
-   }
-   
-   /* Check that the DRM driver version is compatible */
-   if ( (drmActual->major != drmExpected->major)
-	|| (drmActual->minor < drmExpected->minor) ) {
-      fprintf(stderr, format, driver_name, "DRM",
-		       drmExpected->major, drmExpected->minor,
-		       drmActual->major, drmActual->minor, drmActual->patch);
-      return GL_FALSE;
-   }
-
-   return GL_TRUE;
-}
-
-GLboolean
-driCheckDriDdxDrmVersions2(const char * driver_name,
-			   const __DRIversion * driActual,
-			   const __DRIversion * driExpected,
-			   const __DRIversion * ddxActual,
-			   const __DRIversion * ddxExpected,
-			   const __DRIversion * drmActual,
-			   const __DRIversion * drmExpected)
-{
-   __DRIutilversion2 ddx_expected;
-   ddx_expected.major_min = ddxExpected->major;
-   ddx_expected.major_max = ddxExpected->major;
-   ddx_expected.minor = ddxExpected->minor;
-   ddx_expected.patch = ddxExpected->patch;
-   return driCheckDriDdxDrmVersions3(driver_name, driActual,
-				driExpected, ddxActual, & ddx_expected,
-				drmActual, drmExpected);
-}
-
-GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
-				    GLint *x, GLint *y,
-				    GLsizei *width, GLsizei *height )
-{
-   /* left clipping */
-   if (*x < buffer->_Xmin) {
-      *width -= (buffer->_Xmin - *x);
-      *x = buffer->_Xmin;
-   }
-
-   /* right clipping */
-   if (*x + *width > buffer->_Xmax)
-      *width -= (*x + *width - buffer->_Xmax - 1);
-
-   if (*width <= 0)
-      return GL_FALSE;
-
-   /* bottom clipping */
-   if (*y < buffer->_Ymin) {
-      *height -= (buffer->_Ymin - *y);
-      *y = buffer->_Ymin;
-   }
-
-   /* top clipping */
-   if (*y + *height > buffer->_Ymax)
-      *height -= (*y + *height - buffer->_Ymax - 1);
-
-   if (*height <= 0)
-      return GL_FALSE;
-
-   return GL_TRUE;
-}
-
-/**
- * Creates a set of \c struct gl_config that a driver will expose.
- * 
- * A set of \c struct gl_config will be created based on the supplied
- * parameters.  The number of modes processed will be 2 *
- * \c num_depth_stencil_bits * \c num_db_modes.
- * 
- * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
- * \c db_modes, and \c visType into each \c struct gl_config element.
- * However, the meanings of \c fb_format and \c fb_type require further
- * explanation.  The \c fb_format specifies which color components are in
- * each pixel and what the default order is.  For example, \c GL_RGB specifies
- * that red, green, blue are available and red is in the "most significant"
- * position and blue is in the "least significant".  The \c fb_type specifies
- * the bit sizes of each component and the actual ordering.  For example, if
- * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
- * are the blue value, bits [10:5] are the green value, and bits [4:0] are
- * the red value.
- * 
- * One sublte issue is the combination of \c GL_RGB  or \c GL_BGR and either
- * of the \c GL_UNSIGNED_INT_8_8_8_8 modes.  The resulting mask values in the
- * \c struct gl_config structure is \b identical to the \c GL_RGBA or
- * \c GL_BGRA case, except the \c alphaMask is zero.  This means that, as
- * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
- * still uses 32-bits.
- *
- * If in doubt, look at the tables used in the function.
- * 
- * \param ptr_to_modes  Pointer to a pointer to a linked list of
- *                      \c struct gl_config.  Upon completion, a pointer to
- *                      the next element to be process will be stored here.
- *                      If the function fails and returns \c GL_FALSE, this
- *                      value will be unmodified, but some elements in the
- *                      linked list may be modified.
- * \param fb_format     Format of the framebuffer.  Currently only \c GL_RGB,
- *                      \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
- * \param fb_type       Type of the pixels in the framebuffer.  Currently only
- *                      \c GL_UNSIGNED_SHORT_5_6_5, 
- *                      \c GL_UNSIGNED_SHORT_5_6_5_REV,
- *                      \c GL_UNSIGNED_INT_8_8_8_8, and
- *                      \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
- * \param depth_bits    Array of depth buffer sizes to be exposed.
- * \param stencil_bits  Array of stencil buffer sizes to be exposed.
- * \param num_depth_stencil_bits  Number of entries in both \c depth_bits and
- *                      \c stencil_bits.
- * \param db_modes      Array of buffer swap modes.  If an element has a
- *                      value of \c GLX_NONE, then it represents a
- *                      single-buffered mode.  Other valid values are
- *                      \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
- *                      \c GLX_SWAP_UNDEFINED_OML.  See the
- *                      GLX_OML_swap_method extension spec for more details.
- * \param num_db_modes  Number of entries in \c db_modes.
- * \param msaa_samples  Array of msaa sample count. 0 represents a visual
- *                      without a multisample buffer.
- * \param num_msaa_modes Number of entries in \c msaa_samples.
- * \param visType       GLX visual type.  Usually either \c GLX_TRUE_COLOR or
- *                      \c GLX_DIRECT_COLOR.
- * 
- * \returns
- * \c GL_TRUE on success or \c GL_FALSE on failure.  Currently the only
- * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
- * \c fb_type).
- * 
- * \todo
- * There is currently no way to support packed RGB modes (i.e., modes with
- * exactly 3 bytes per pixel) or floating-point modes.  This could probably
- * be done by creating some new, private enums with clever names likes
- * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32, 
- * \c GL_4HALF_16_16_16_16, etc.  We can cross that bridge when we come to it.
- */
-__DRIconfig **
-driCreateConfigs(GLenum fb_format, GLenum fb_type,
-		 const uint8_t * depth_bits, const uint8_t * stencil_bits,
-		 unsigned num_depth_stencil_bits,
-		 const GLenum * db_modes, unsigned num_db_modes,
-		 const uint8_t * msaa_samples, unsigned num_msaa_modes,
-		 GLboolean enable_accum)
-{
-   static const uint8_t bits_table[4][4] = {
-     /* R  G  B  A */
-      { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
-      { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
-      { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
-      { 8, 8, 8, 8 }  /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
-   };
-
-   static const uint32_t masks_table_rgb[6][4] = {
-      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2       */
-      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV   */
-      { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5       */
-      { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV   */
-      { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8     */
-      { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }  /* 8_8_8_8_REV */
-   };
-
-   static const uint32_t masks_table_rgba[6][4] = {
-      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2       */
-      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV   */
-      { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5       */
-      { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV   */
-      { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8     */
-      { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
-   };
-
-   static const uint32_t masks_table_bgr[6][4] = {
-      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2       */
-      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV   */
-      { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5       */
-      { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV   */
-      { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8     */
-      { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
-   };
-
-   static const uint32_t masks_table_bgra[6][4] = {
-      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2       */
-      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV   */
-      { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5       */
-      { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV   */
-      { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8     */
-      { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
-   };
-
-   static const uint8_t bytes_per_pixel[6] = {
-      1, /* 3_3_2       */
-      1, /* 2_3_3_REV   */
-      2, /* 5_6_5       */
-      2, /* 5_6_5_REV   */
-      4, /* 8_8_8_8     */
-      4  /* 8_8_8_8_REV */
-   };
-
-   const uint8_t  * bits;
-   const uint32_t * masks;
-   int index;
-   __DRIconfig **configs, **c;
-   struct gl_config *modes;
-   unsigned i, j, k, h;
-   unsigned num_modes;
-   unsigned num_accum_bits = (enable_accum) ? 2 : 1;
-
-   switch ( fb_type ) {
-      case GL_UNSIGNED_BYTE_3_3_2:
-	 index = 0;
-	 break;
-      case GL_UNSIGNED_BYTE_2_3_3_REV:
-	 index = 1;
-	 break;
-      case GL_UNSIGNED_SHORT_5_6_5:
-	 index = 2;
-	 break;
-      case GL_UNSIGNED_SHORT_5_6_5_REV:
-	 index = 3;
-	 break;
-      case GL_UNSIGNED_INT_8_8_8_8:
-	 index = 4;
-	 break;
-      case GL_UNSIGNED_INT_8_8_8_8_REV:
-	 index = 5;
-	 break;
-      default:
-	 fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
-               __FUNCTION__, __LINE__, fb_type );
-	 return NULL;
-   }
-
-
-   /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
-    * the _REV versions.
-    *
-    * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
-    */
-
-   switch ( fb_format ) {
-      case GL_RGB:
-         masks = masks_table_rgb[ index ];
-         break;
-
-      case GL_RGBA:
-         masks = masks_table_rgba[ index ];
-         break;
-
-      case GL_BGR:
-         masks = masks_table_bgr[ index ];
-         break;
-
-      case GL_BGRA:
-         masks = masks_table_bgra[ index ];
-         break;
-
-      default:
-         fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
-               __FUNCTION__, __LINE__, fb_format );
-         return NULL;
-   }
-
-   switch ( bytes_per_pixel[ index ] ) {
-      case 1:
-	 bits = bits_table[0];
-	 break;
-      case 2:
-	 bits = bits_table[1];
-	 break;
-      default:
-	 bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
-	    ? bits_table[2]
-	    : bits_table[3];
-	 break;
-   }
-
-   num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes;
-   configs = calloc(1, (num_modes + 1) * sizeof *configs);
-   if (configs == NULL)
-       return NULL;
-
-    c = configs;
-    for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
-	for ( i = 0 ; i < num_db_modes ; i++ ) {
-	    for ( h = 0 ; h < num_msaa_modes; h++ ) {
-	    	for ( j = 0 ; j < num_accum_bits ; j++ ) {
-		    *c = malloc (sizeof **c);
-		    modes = &(*c)->modes;
-		    c++;
-
-		    memset(modes, 0, sizeof *modes);
-		    modes->redBits   = bits[0];
-		    modes->greenBits = bits[1];
-		    modes->blueBits  = bits[2];
-		    modes->alphaBits = bits[3];
-		    modes->redMask   = masks[0];
-		    modes->greenMask = masks[1];
-		    modes->blueMask  = masks[2];
-		    modes->alphaMask = masks[3];
-		    modes->rgbBits   = modes->redBits + modes->greenBits
-		    	+ modes->blueBits + modes->alphaBits;
-
-		    modes->accumRedBits   = 16 * j;
-		    modes->accumGreenBits = 16 * j;
-		    modes->accumBlueBits  = 16 * j;
-		    modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
-		    modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
-
-		    modes->stencilBits = stencil_bits[k];
-		    modes->depthBits = depth_bits[k];
-
-		    modes->transparentPixel = GLX_NONE;
-		    modes->transparentRed = GLX_DONT_CARE;
-		    modes->transparentGreen = GLX_DONT_CARE;
-		    modes->transparentBlue = GLX_DONT_CARE;
-		    modes->transparentAlpha = GLX_DONT_CARE;
-		    modes->transparentIndex = GLX_DONT_CARE;
-		    modes->rgbMode = GL_TRUE;
-
-		    if ( db_modes[i] == GLX_NONE ) {
-		    	modes->doubleBufferMode = GL_FALSE;
-		    }
-		    else {
-		    	modes->doubleBufferMode = GL_TRUE;
-		    	modes->swapMethod = db_modes[i];
-		    }
-
-		    modes->samples = msaa_samples[h];
-		    modes->sampleBuffers = modes->samples ? 1 : 0;
-
-
-		    modes->haveAccumBuffer = ((modes->accumRedBits +
-					   modes->accumGreenBits +
-					   modes->accumBlueBits +
-					   modes->accumAlphaBits) > 0);
-		    modes->haveDepthBuffer = (modes->depthBits > 0);
-		    modes->haveStencilBuffer = (modes->stencilBits > 0);
-
-		    modes->bindToTextureRgb = GL_TRUE;
-		    modes->bindToTextureRgba = GL_TRUE;
-		    modes->bindToMipmapTexture = GL_FALSE;
-		    modes->bindToTextureTargets =
-			__DRI_ATTRIB_TEXTURE_1D_BIT |
-			__DRI_ATTRIB_TEXTURE_2D_BIT |
-			__DRI_ATTRIB_TEXTURE_RECTANGLE_BIT;
-
-		    modes->sRGBCapable = GL_FALSE;
-		}
-	    }
-	}
-    }
-    *c = NULL;
-
-    return configs;
-}
-
-__DRIconfig **driConcatConfigs(__DRIconfig **a,
-			       __DRIconfig **b)
-{
-    __DRIconfig **all;
-    int i, j, index;
-
-    i = 0;
-    while (a[i] != NULL)
-	i++;
-    j = 0;
-    while (b[j] != NULL)
-	j++;
-   
-    all = malloc((i + j + 1) * sizeof *all);
-    index = 0;
-    for (i = 0; a[i] != NULL; i++)
-	all[index++] = a[i];
-    for (j = 0; b[j] != NULL; j++)
-	all[index++] = b[j];
-    all[index++] = NULL;
-
-    free(a);
-    free(b);
-
-    return all;
-}
-
-#define __ATTRIB(attrib, field) \
-    { attrib, offsetof(struct gl_config, field) }
-
-static const struct { unsigned int attrib, offset; } attribMap[] = {
-    __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE,			rgbBits),
-    __ATTRIB(__DRI_ATTRIB_LEVEL,			level),
-    __ATTRIB(__DRI_ATTRIB_RED_SIZE,			redBits),
-    __ATTRIB(__DRI_ATTRIB_GREEN_SIZE,			greenBits),
-    __ATTRIB(__DRI_ATTRIB_BLUE_SIZE,			blueBits),
-    __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE,			alphaBits),
-    __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE,			depthBits),
-    __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE,			stencilBits),
-    __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE,		accumRedBits),
-    __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE,		accumGreenBits),
-    __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE,		accumBlueBits),
-    __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE,		accumAlphaBits),
-    __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS,		sampleBuffers),
-    __ATTRIB(__DRI_ATTRIB_SAMPLES,			samples),
-    __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER,		doubleBufferMode),
-    __ATTRIB(__DRI_ATTRIB_STEREO,			stereoMode),
-    __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS,			numAuxBuffers),
-    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE,		transparentPixel),
-    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE,	transparentPixel),
-    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE,	transparentRed),
-    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE,	transparentGreen),
-    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE,	transparentBlue),
-    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE,	transparentAlpha),
-    __ATTRIB(__DRI_ATTRIB_FLOAT_MODE,			floatMode),
-    __ATTRIB(__DRI_ATTRIB_RED_MASK,			redMask),
-    __ATTRIB(__DRI_ATTRIB_GREEN_MASK,			greenMask),
-    __ATTRIB(__DRI_ATTRIB_BLUE_MASK,			blueMask),
-    __ATTRIB(__DRI_ATTRIB_ALPHA_MASK,			alphaMask),
-    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH,		maxPbufferWidth),
-    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT,		maxPbufferHeight),
-    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS,		maxPbufferPixels),
-    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH,	optimalPbufferWidth),
-    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT,	optimalPbufferHeight),
-    __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,			swapMethod),
-    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB,		bindToTextureRgb),
-    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA,		bindToTextureRgba),
-    __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE,	bindToMipmapTexture),
-    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS,	bindToTextureTargets),
-    __ATTRIB(__DRI_ATTRIB_YINVERTED,			yInverted),
-    __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE,	sRGBCapable),
-
-    /* The struct field doesn't matter here, these are handled by the
-     * switch in driGetConfigAttribIndex.  We need them in the array
-     * so the iterator includes them though.*/
-    __ATTRIB(__DRI_ATTRIB_RENDER_TYPE,			level),
-    __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT,		level),
-    __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,			level)
-};
-
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-
-
-/**
- * Return the value of a configuration attribute.  The attribute is
- * indicated by the index.
- */
-static int
-driGetConfigAttribIndex(const __DRIconfig *config,
-			unsigned int index, unsigned int *value)
-{
-    switch (attribMap[index].attrib) {
-    case __DRI_ATTRIB_RENDER_TYPE:
-        /* no support for color index mode */
-	*value = __DRI_ATTRIB_RGBA_BIT;
-	break;
-    case __DRI_ATTRIB_CONFIG_CAVEAT:
-	if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
-	    *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
-	else if (config->modes.visualRating == GLX_SLOW_CONFIG)
-	    *value = __DRI_ATTRIB_SLOW_BIT;
-	else
-	    *value = 0;
-	break;
-    case __DRI_ATTRIB_SWAP_METHOD:
-        /* XXX no return value??? */
-	break;
-
-    case __DRI_ATTRIB_FLOAT_MODE:
-        /* this field is not int-sized */
-        *value = config->modes.floatMode;
-        break;
-
-    default:
-        /* any other int-sized field */
-	*value = *(unsigned int *)
-	    ((char *) &config->modes + attribMap[index].offset);
-	
-	break;
-    }
-
-    return GL_TRUE;
-}
-
-
-/**
- * Get the value of a configuration attribute.
- * \param attrib  the attribute (one of the _DRI_ATTRIB_x tokens)
- * \param value  returns the attribute's value
- * \return 1 for success, 0 for failure
- */
-int
-driGetConfigAttrib(const __DRIconfig *config,
-		   unsigned int attrib, unsigned int *value)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(attribMap); i++)
-	if (attribMap[i].attrib == attrib)
-	    return driGetConfigAttribIndex(config, i, value);
-
-    return GL_FALSE;
-}
-
-
-/**
- * Get a configuration attribute name and value, given an index.
- * \param index  which field of the __DRIconfig to query
- * \param attrib  returns the attribute name (one of the _DRI_ATTRIB_x tokens)
- * \param value  returns the attribute's value
- * \return 1 for success, 0 for failure
- */
-int
-driIndexConfigAttrib(const __DRIconfig *config, int index,
-		     unsigned int *attrib, unsigned int *value)
-{
-    if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
-	*attrib = attribMap[index].attrib;
-	return driGetConfigAttribIndex(config, index, value);
-    }
-
-    return GL_FALSE;
-}
+/*
+ * (C) Copyright IBM Corporation 2002, 2004
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file utils.c
+ * Utility functions for DRI drivers.
+ *
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include "main/mtypes.h"
+#include "main/cpuinfo.h"
+#include "main/extensions.h"
+#include "utils.h"
+
+
+/**
+ * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
+ * is set. 
+ * 
+ * Is called from the drivers.
+ * 
+ * \param f \c printf like format string.
+ */
+void
+__driUtilMessage(const char *f, ...)
+{
+    va_list args;
+
+    if (getenv("LIBGL_DEBUG")) {
+        fprintf(stderr, "libGL: ");
+        va_start(args, f);
+        vfprintf(stderr, f, args);
+        va_end(args);
+        fprintf(stderr, "\n");
+    }
+}
+
+
+unsigned
+driParseDebugString( const char * debug, 
+		     const struct dri_debug_control * control  )
+{
+   unsigned   flag;
+
+
+   flag = 0;
+   if ( debug != NULL ) {
+      while( control->string != NULL ) {
+	 if ( !strcmp( debug, "all" ) ||
+	      strstr( debug, control->string ) != NULL ) {
+	    flag |= control->flag;
+	 }
+
+	 control++;
+      }
+   }
+
+   return flag;
+}
+
+
+
+/**
+ * Create the \c GL_RENDERER string for DRI drivers.
+ * 
+ * Almost all DRI drivers use a \c GL_RENDERER string of the form:
+ *
+ *    "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>"
+ *
+ * Using the supplied chip name, driver data, and AGP speed, this function
+ * creates the string.
+ * 
+ * \param buffer         Buffer to hold the \c GL_RENDERER string.
+ * \param hardware_name  Name of the hardware.
+ * \param agp_mode       AGP mode (speed).
+ * 
+ * \returns
+ * The length of the string stored in \c buffer.  This does \b not include
+ * the terminating \c NUL character.
+ */
+unsigned
+driGetRendererString( char * buffer, const char * hardware_name,
+		      GLuint agp_mode )
+{
+   unsigned offset;
+   char *cpu;
+
+   offset = sprintf( buffer, "Mesa DRI %s", hardware_name );
+
+   /* Append any AGP-specific information.
+    */
+   switch ( agp_mode ) {
+   case 1:
+   case 2:
+   case 4:
+   case 8:
+      offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode );
+      break;
+	
+   default:
+      break;
+   }
+
+   /* Append any CPU-specific information.
+    */
+   cpu = _mesa_get_cpu_string();
+   if (cpu) {
+      offset += sprintf(buffer + offset, " %s", cpu);
+      free(cpu);
+   }
+
+   return offset;
+}
+
+
+/**
+ * Utility function used by drivers to test the verions of other components.
+ *
+ * \param driver_name  Name of the driver.  Used in error messages.
+ * \param driActual    Actual DRI version supplied __driCreateNewScreen.
+ * \param driExpected  Minimum DRI version required by the driver.
+ * \param ddxActual    Actual DDX version supplied __driCreateNewScreen.
+ * \param ddxExpected  Minimum DDX minor and range of DDX major version required by the driver.
+ * \param drmActual    Actual DRM version supplied __driCreateNewScreen.
+ * \param drmExpected  Minimum DRM version required by the driver.
+ * 
+ * \returns \c GL_TRUE if all version requirements are met.  Otherwise,
+ *          \c GL_FALSE is returned.
+ * 
+ * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2
+ *
+ * \todo
+ * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
+ * function and \c driCheckDriDdxDrmVersions2 should be renamed.
+ */
+GLboolean
+driCheckDriDdxDrmVersions3(const char * driver_name,
+			   const __DRIversion * driActual,
+			   const __DRIversion * driExpected,
+			   const __DRIversion * ddxActual,
+			   const __DRIutilversion2 * ddxExpected,
+			   const __DRIversion * drmActual,
+			   const __DRIversion * drmExpected)
+{
+   static const char format[] = "%s DRI driver expected %s version %d.%d.x "
+       "but got version %d.%d.%d\n";
+   static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x "
+       "but got version %d.%d.%d\n";
+
+
+   /* Check the DRI version */
+   if ( (driActual->major != driExpected->major)
+	|| (driActual->minor < driExpected->minor) ) {
+      fprintf(stderr, format, driver_name, "DRI",
+		       driExpected->major, driExpected->minor,
+		       driActual->major, driActual->minor, driActual->patch);
+      return GL_FALSE;
+   }
+
+   /* Check that the DDX driver version is compatible */
+   if ( (ddxActual->major < ddxExpected->major_min)
+	|| (ddxActual->major > ddxExpected->major_max)
+	|| (ddxActual->minor < ddxExpected->minor) ) {
+      fprintf(stderr, format2, driver_name, "DDX",
+		       ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor,
+		       ddxActual->major, ddxActual->minor, ddxActual->patch);
+      return GL_FALSE;
+   }
+   
+   /* Check that the DRM driver version is compatible */
+   if ( (drmActual->major != drmExpected->major)
+	|| (drmActual->minor < drmExpected->minor) ) {
+      fprintf(stderr, format, driver_name, "DRM",
+		       drmExpected->major, drmExpected->minor,
+		       drmActual->major, drmActual->minor, drmActual->patch);
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+GLboolean
+driCheckDriDdxDrmVersions2(const char * driver_name,
+			   const __DRIversion * driActual,
+			   const __DRIversion * driExpected,
+			   const __DRIversion * ddxActual,
+			   const __DRIversion * ddxExpected,
+			   const __DRIversion * drmActual,
+			   const __DRIversion * drmExpected)
+{
+   __DRIutilversion2 ddx_expected;
+   ddx_expected.major_min = ddxExpected->major;
+   ddx_expected.major_max = ddxExpected->major;
+   ddx_expected.minor = ddxExpected->minor;
+   ddx_expected.patch = ddxExpected->patch;
+   return driCheckDriDdxDrmVersions3(driver_name, driActual,
+				driExpected, ddxActual, & ddx_expected,
+				drmActual, drmExpected);
+}
+
+GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
+				    GLint *x, GLint *y,
+				    GLsizei *width, GLsizei *height )
+{
+   /* left clipping */
+   if (*x < buffer->_Xmin) {
+      *width -= (buffer->_Xmin - *x);
+      *x = buffer->_Xmin;
+   }
+
+   /* right clipping */
+   if (*x + *width > buffer->_Xmax)
+      *width -= (*x + *width - buffer->_Xmax - 1);
+
+   if (*width <= 0)
+      return GL_FALSE;
+
+   /* bottom clipping */
+   if (*y < buffer->_Ymin) {
+      *height -= (buffer->_Ymin - *y);
+      *y = buffer->_Ymin;
+   }
+
+   /* top clipping */
+   if (*y + *height > buffer->_Ymax)
+      *height -= (*y + *height - buffer->_Ymax - 1);
+
+   if (*height <= 0)
+      return GL_FALSE;
+
+   return GL_TRUE;
+}
+
+/**
+ * Creates a set of \c struct gl_config that a driver will expose.
+ * 
+ * A set of \c struct gl_config will be created based on the supplied
+ * parameters.  The number of modes processed will be 2 *
+ * \c num_depth_stencil_bits * \c num_db_modes.
+ * 
+ * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
+ * \c db_modes, and \c visType into each \c struct gl_config element.
+ * However, the meanings of \c fb_format and \c fb_type require further
+ * explanation.  The \c fb_format specifies which color components are in
+ * each pixel and what the default order is.  For example, \c GL_RGB specifies
+ * that red, green, blue are available and red is in the "most significant"
+ * position and blue is in the "least significant".  The \c fb_type specifies
+ * the bit sizes of each component and the actual ordering.  For example, if
+ * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
+ * are the blue value, bits [10:5] are the green value, and bits [4:0] are
+ * the red value.
+ * 
+ * One sublte issue is the combination of \c GL_RGB  or \c GL_BGR and either
+ * of the \c GL_UNSIGNED_INT_8_8_8_8 modes.  The resulting mask values in the
+ * \c struct gl_config structure is \b identical to the \c GL_RGBA or
+ * \c GL_BGRA case, except the \c alphaMask is zero.  This means that, as
+ * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
+ * still uses 32-bits.
+ *
+ * If in doubt, look at the tables used in the function.
+ * 
+ * \param ptr_to_modes  Pointer to a pointer to a linked list of
+ *                      \c struct gl_config.  Upon completion, a pointer to
+ *                      the next element to be process will be stored here.
+ *                      If the function fails and returns \c GL_FALSE, this
+ *                      value will be unmodified, but some elements in the
+ *                      linked list may be modified.
+ * \param fb_format     Format of the framebuffer.  Currently only \c GL_RGB,
+ *                      \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
+ * \param fb_type       Type of the pixels in the framebuffer.  Currently only
+ *                      \c GL_UNSIGNED_SHORT_5_6_5, 
+ *                      \c GL_UNSIGNED_SHORT_5_6_5_REV,
+ *                      \c GL_UNSIGNED_INT_8_8_8_8, and
+ *                      \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
+ * \param depth_bits    Array of depth buffer sizes to be exposed.
+ * \param stencil_bits  Array of stencil buffer sizes to be exposed.
+ * \param num_depth_stencil_bits  Number of entries in both \c depth_bits and
+ *                      \c stencil_bits.
+ * \param db_modes      Array of buffer swap modes.  If an element has a
+ *                      value of \c GLX_NONE, then it represents a
+ *                      single-buffered mode.  Other valid values are
+ *                      \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
+ *                      \c GLX_SWAP_UNDEFINED_OML.  See the
+ *                      GLX_OML_swap_method extension spec for more details.
+ * \param num_db_modes  Number of entries in \c db_modes.
+ * \param msaa_samples  Array of msaa sample count. 0 represents a visual
+ *                      without a multisample buffer.
+ * \param num_msaa_modes Number of entries in \c msaa_samples.
+ * \param visType       GLX visual type.  Usually either \c GLX_TRUE_COLOR or
+ *                      \c GLX_DIRECT_COLOR.
+ * 
+ * \returns
+ * \c GL_TRUE on success or \c GL_FALSE on failure.  Currently the only
+ * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
+ * \c fb_type).
+ * 
+ * \todo
+ * There is currently no way to support packed RGB modes (i.e., modes with
+ * exactly 3 bytes per pixel) or floating-point modes.  This could probably
+ * be done by creating some new, private enums with clever names likes
+ * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32, 
+ * \c GL_4HALF_16_16_16_16, etc.  We can cross that bridge when we come to it.
+ */
+__DRIconfig **
+driCreateConfigs(GLenum fb_format, GLenum fb_type,
+		 const uint8_t * depth_bits, const uint8_t * stencil_bits,
+		 unsigned num_depth_stencil_bits,
+		 const GLenum * db_modes, unsigned num_db_modes,
+		 const uint8_t * msaa_samples, unsigned num_msaa_modes,
+		 GLboolean enable_accum)
+{
+   static const uint8_t bits_table[4][4] = {
+     /* R  G  B  A */
+      { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
+      { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
+      { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
+      { 8, 8, 8, 8 }  /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
+   };
+
+   static const uint32_t masks_table_rgb[6][4] = {
+      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2       */
+      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV   */
+      { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5       */
+      { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV   */
+      { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8     */
+      { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }  /* 8_8_8_8_REV */
+   };
+
+   static const uint32_t masks_table_rgba[6][4] = {
+      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2       */
+      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV   */
+      { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5       */
+      { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV   */
+      { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8     */
+      { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
+   };
+
+   static const uint32_t masks_table_bgr[6][4] = {
+      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2       */
+      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV   */
+      { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5       */
+      { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV   */
+      { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8     */
+      { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
+   };
+
+   static const uint32_t masks_table_bgra[6][4] = {
+      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2       */
+      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV   */
+      { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5       */
+      { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV   */
+      { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8     */
+      { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
+   };
+
+   static const uint8_t bytes_per_pixel[6] = {
+      1, /* 3_3_2       */
+      1, /* 2_3_3_REV   */
+      2, /* 5_6_5       */
+      2, /* 5_6_5_REV   */
+      4, /* 8_8_8_8     */
+      4  /* 8_8_8_8_REV */
+   };
+
+   const uint8_t  * bits;
+   const uint32_t * masks;
+   int index;
+   __DRIconfig **configs, **c;
+   struct gl_config *modes;
+   unsigned i, j, k, h;
+   unsigned num_modes;
+   unsigned num_accum_bits = (enable_accum) ? 2 : 1;
+
+   switch ( fb_type ) {
+      case GL_UNSIGNED_BYTE_3_3_2:
+	 index = 0;
+	 break;
+      case GL_UNSIGNED_BYTE_2_3_3_REV:
+	 index = 1;
+	 break;
+      case GL_UNSIGNED_SHORT_5_6_5:
+	 index = 2;
+	 break;
+      case GL_UNSIGNED_SHORT_5_6_5_REV:
+	 index = 3;
+	 break;
+      case GL_UNSIGNED_INT_8_8_8_8:
+	 index = 4;
+	 break;
+      case GL_UNSIGNED_INT_8_8_8_8_REV:
+	 index = 5;
+	 break;
+      default:
+	 fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
+               __FUNCTION__, __LINE__, fb_type );
+	 return NULL;
+   }
+
+
+   /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
+    * the _REV versions.
+    *
+    * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
+    */
+
+   switch ( fb_format ) {
+      case GL_RGB:
+         masks = masks_table_rgb[ index ];
+         break;
+
+      case GL_RGBA:
+         masks = masks_table_rgba[ index ];
+         break;
+
+      case GL_BGR:
+         masks = masks_table_bgr[ index ];
+         break;
+
+      case GL_BGRA:
+         masks = masks_table_bgra[ index ];
+         break;
+
+      default:
+         fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
+               __FUNCTION__, __LINE__, fb_format );
+         return NULL;
+   }
+
+   switch ( bytes_per_pixel[ index ] ) {
+      case 1:
+	 bits = bits_table[0];
+	 break;
+      case 2:
+	 bits = bits_table[1];
+	 break;
+      default:
+	 bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
+	    ? bits_table[2]
+	    : bits_table[3];
+	 break;
+   }
+
+   num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes;
+   configs = calloc(1, (num_modes + 1) * sizeof *configs);
+   if (configs == NULL)
+       return NULL;
+
+    c = configs;
+    for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
+	for ( i = 0 ; i < num_db_modes ; i++ ) {
+	    for ( h = 0 ; h < num_msaa_modes; h++ ) {
+	    	for ( j = 0 ; j < num_accum_bits ; j++ ) {
+		    *c = malloc (sizeof **c);
+		    modes = &(*c)->modes;
+		    c++;
+
+		    memset(modes, 0, sizeof *modes);
+		    modes->redBits   = bits[0];
+		    modes->greenBits = bits[1];
+		    modes->blueBits  = bits[2];
+		    modes->alphaBits = bits[3];
+		    modes->redMask   = masks[0];
+		    modes->greenMask = masks[1];
+		    modes->blueMask  = masks[2];
+		    modes->alphaMask = masks[3];
+		    modes->rgbBits   = modes->redBits + modes->greenBits
+		    	+ modes->blueBits + modes->alphaBits;
+
+		    modes->accumRedBits   = 16 * j;
+		    modes->accumGreenBits = 16 * j;
+		    modes->accumBlueBits  = 16 * j;
+		    modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
+		    modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
+
+		    modes->stencilBits = stencil_bits[k];
+		    modes->depthBits = depth_bits[k];
+
+		    modes->transparentPixel = GLX_NONE;
+		    modes->transparentRed = GLX_DONT_CARE;
+		    modes->transparentGreen = GLX_DONT_CARE;
+		    modes->transparentBlue = GLX_DONT_CARE;
+		    modes->transparentAlpha = GLX_DONT_CARE;
+		    modes->transparentIndex = GLX_DONT_CARE;
+		    modes->rgbMode = GL_TRUE;
+
+		    if ( db_modes[i] == GLX_NONE ) {
+		    	modes->doubleBufferMode = GL_FALSE;
+		    }
+		    else {
+		    	modes->doubleBufferMode = GL_TRUE;
+		    	modes->swapMethod = db_modes[i];
+		    }
+
+		    modes->samples = msaa_samples[h];
+		    modes->sampleBuffers = modes->samples ? 1 : 0;
+
+
+		    modes->haveAccumBuffer = ((modes->accumRedBits +
+					   modes->accumGreenBits +
+					   modes->accumBlueBits +
+					   modes->accumAlphaBits) > 0);
+		    modes->haveDepthBuffer = (modes->depthBits > 0);
+		    modes->haveStencilBuffer = (modes->stencilBits > 0);
+
+		    modes->bindToTextureRgb = GL_TRUE;
+		    modes->bindToTextureRgba = GL_TRUE;
+		    modes->bindToMipmapTexture = GL_FALSE;
+		    modes->bindToTextureTargets =
+			__DRI_ATTRIB_TEXTURE_1D_BIT |
+			__DRI_ATTRIB_TEXTURE_2D_BIT |
+			__DRI_ATTRIB_TEXTURE_RECTANGLE_BIT;
+
+		    modes->sRGBCapable = GL_FALSE;
+		}
+	    }
+	}
+    }
+    *c = NULL;
+
+    return configs;
+}
+
+__DRIconfig **driConcatConfigs(__DRIconfig **a,
+			       __DRIconfig **b)
+{
+    __DRIconfig **all;
+    int i, j, index;
+
+    i = 0;
+    while (a[i] != NULL)
+	i++;
+    j = 0;
+    while (b[j] != NULL)
+	j++;
+   
+    all = malloc((i + j + 1) * sizeof *all);
+    index = 0;
+    for (i = 0; a[i] != NULL; i++)
+	all[index++] = a[i];
+    for (j = 0; b[j] != NULL; j++)
+	all[index++] = b[j];
+    all[index++] = NULL;
+
+    free(a);
+    free(b);
+
+    return all;
+}
+
+#define __ATTRIB(attrib, field) \
+    { attrib, offsetof(struct gl_config, field) }
+
+static const struct { unsigned int attrib, offset; } attribMap[] = {
+    __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE,			rgbBits),
+    __ATTRIB(__DRI_ATTRIB_LEVEL,			level),
+    __ATTRIB(__DRI_ATTRIB_RED_SIZE,			redBits),
+    __ATTRIB(__DRI_ATTRIB_GREEN_SIZE,			greenBits),
+    __ATTRIB(__DRI_ATTRIB_BLUE_SIZE,			blueBits),
+    __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE,			alphaBits),
+    __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE,			depthBits),
+    __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE,			stencilBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE,		accumRedBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE,		accumGreenBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE,		accumBlueBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE,		accumAlphaBits),
+    __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS,		sampleBuffers),
+    __ATTRIB(__DRI_ATTRIB_SAMPLES,			samples),
+    __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER,		doubleBufferMode),
+    __ATTRIB(__DRI_ATTRIB_STEREO,			stereoMode),
+    __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS,			numAuxBuffers),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE,		transparentPixel),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE,	transparentPixel),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE,	transparentRed),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE,	transparentGreen),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE,	transparentBlue),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE,	transparentAlpha),
+    __ATTRIB(__DRI_ATTRIB_FLOAT_MODE,			floatMode),
+    __ATTRIB(__DRI_ATTRIB_RED_MASK,			redMask),
+    __ATTRIB(__DRI_ATTRIB_GREEN_MASK,			greenMask),
+    __ATTRIB(__DRI_ATTRIB_BLUE_MASK,			blueMask),
+    __ATTRIB(__DRI_ATTRIB_ALPHA_MASK,			alphaMask),
+    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH,		maxPbufferWidth),
+    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT,		maxPbufferHeight),
+    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS,		maxPbufferPixels),
+    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH,	optimalPbufferWidth),
+    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT,	optimalPbufferHeight),
+    __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,			swapMethod),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB,		bindToTextureRgb),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA,		bindToTextureRgba),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE,	bindToMipmapTexture),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS,	bindToTextureTargets),
+    __ATTRIB(__DRI_ATTRIB_YINVERTED,			yInverted),
+    __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE,	sRGBCapable),
+
+    /* The struct field doesn't matter here, these are handled by the
+     * switch in driGetConfigAttribIndex.  We need them in the array
+     * so the iterator includes them though.*/
+    __ATTRIB(__DRI_ATTRIB_RENDER_TYPE,			level),
+    __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT,		level),
+    __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,			level)
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+
+/**
+ * Return the value of a configuration attribute.  The attribute is
+ * indicated by the index.
+ */
+static int
+driGetConfigAttribIndex(const __DRIconfig *config,
+			unsigned int index, unsigned int *value)
+{
+    switch (attribMap[index].attrib) {
+    case __DRI_ATTRIB_RENDER_TYPE:
+        /* no support for color index mode */
+	*value = __DRI_ATTRIB_RGBA_BIT;
+	break;
+    case __DRI_ATTRIB_CONFIG_CAVEAT:
+	if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
+	    *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
+	else if (config->modes.visualRating == GLX_SLOW_CONFIG)
+	    *value = __DRI_ATTRIB_SLOW_BIT;
+	else
+	    *value = 0;
+	break;
+    case __DRI_ATTRIB_SWAP_METHOD:
+        /* XXX no return value??? */
+	break;
+
+    case __DRI_ATTRIB_FLOAT_MODE:
+        /* this field is not int-sized */
+        *value = config->modes.floatMode;
+        break;
+
+    default:
+        /* any other int-sized field */
+	*value = *(unsigned int *)
+	    ((char *) &config->modes + attribMap[index].offset);
+	
+	break;
+    }
+
+    return GL_TRUE;
+}
+
+
+/**
+ * Get the value of a configuration attribute.
+ * \param attrib  the attribute (one of the _DRI_ATTRIB_x tokens)
+ * \param value  returns the attribute's value
+ * \return 1 for success, 0 for failure
+ */
+int
+driGetConfigAttrib(const __DRIconfig *config,
+		   unsigned int attrib, unsigned int *value)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(attribMap); i++)
+	if (attribMap[i].attrib == attrib)
+	    return driGetConfigAttribIndex(config, i, value);
+
+    return GL_FALSE;
+}
+
+
+/**
+ * Get a configuration attribute name and value, given an index.
+ * \param index  which field of the __DRIconfig to query
+ * \param attrib  returns the attribute name (one of the _DRI_ATTRIB_x tokens)
+ * \param value  returns the attribute's value
+ * \return 1 for success, 0 for failure
+ */
+int
+driIndexConfigAttrib(const __DRIconfig *config, int index,
+		     unsigned int *attrib, unsigned int *value)
+{
+    if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
+	*attrib = attribMap[index].attrib;
+	return driGetConfigAttribIndex(config, index, value);
+    }
+
+    return GL_FALSE;
+}
diff --git a/mesalib/src/mesa/drivers/dri/common/utils.h b/mesalib/src/mesa/drivers/dri/common/utils.h
index 10fb23de9..100d0dd51 100644
--- a/mesalib/src/mesa/drivers/dri/common/utils.h
+++ b/mesalib/src/mesa/drivers/dri/common/utils.h
@@ -1,123 +1,98 @@
-/*
- * (C) Copyright IBM Corporation 2002, 2004
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Ian Romanick <idr@us.ibm.com>
- */
-
-#ifndef DRI_DEBUG_H
-#define DRI_DEBUG_H
-
-#include <GL/gl.h>
-#include <GL/internal/dri_interface.h>
-#include "main/context.h"
-#include "main/remap.h"
-
-typedef struct __DRIutilversionRec2    __DRIutilversion2;
-
-struct dri_debug_control {
-    const char * string;
-    unsigned     flag;
-};
-
-/**
- * Description of the API for an extension to OpenGL.
- */
-struct dri_extension {
-    /**
-     * Name of the extension.
-     */
-    const char * name;
-    
-
-    /**
-     * Pointer to a list of \c dri_extension_function structures.  The list
-     * is terminated by a structure with a \c NULL
-     * \c dri_extension_function::strings pointer.
-     */
-    const struct gl_function_remap * functions;
-};
-
-/**
- * Used to store a version which includes a major range instead of a single
- * major version number.
- */
-struct __DRIutilversionRec2 {
-    int    major_min;    /** min allowed Major version number. */
-    int    major_max;    /** max allowed Major version number. */
-    int    minor;        /**< Minor version number. */
-    int    patch;        /**< Patch-level. */
-};
-
-extern void
-__driUtilMessage(const char *f, ...);
-
-extern unsigned driParseDebugString( const char * debug,
-    const struct dri_debug_control * control );
-
-extern unsigned driGetRendererString( char * buffer,
-    const char * hardware_name, GLuint agp_mode );
-
-extern void driInitExtensions( struct gl_context * ctx, 
-    const struct dri_extension * card_extensions, GLboolean enable_imaging );
-
-extern void driInitSingleExtension( struct gl_context * ctx,
-    const struct dri_extension * ext );
-
-extern GLboolean driCheckDriDdxDrmVersions2(const char * driver_name,
-    const __DRIversion * driActual, const __DRIversion * driExpected,
-    const __DRIversion * ddxActual, const __DRIversion * ddxExpected,
-    const __DRIversion * drmActual, const __DRIversion * drmExpected);
-
-extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name,
-    const __DRIversion * driActual, const __DRIversion * driExpected,
-    const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected,
-    const __DRIversion * drmActual, const __DRIversion * drmExpected);
-
-extern GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
-					   GLint *x, GLint *y,
-					   GLsizei *width, GLsizei *height );
-
-struct __DRIconfigRec {
-    struct gl_config modes;
-};
-
-extern __DRIconfig **
-driCreateConfigs(GLenum fb_format, GLenum fb_type,
-		 const uint8_t * depth_bits, const uint8_t * stencil_bits,
-		 unsigned num_depth_stencil_bits,
-		 const GLenum * db_modes, unsigned num_db_modes,
-		 const uint8_t * msaa_samples, unsigned num_msaa_modes,
-		 GLboolean enable_accum);
-
-__DRIconfig **driConcatConfigs(__DRIconfig **a,
-			       __DRIconfig **b);
-
-int
-driGetConfigAttrib(const __DRIconfig *config,
-		   unsigned int attrib, unsigned int *value);
-int
-driIndexConfigAttrib(const __DRIconfig *config, int index,
-		     unsigned int *attrib, unsigned int *value);
-
-#endif /* DRI_DEBUG_H */
+/*
+ * (C) Copyright IBM Corporation 2002, 2004
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Ian Romanick <idr@us.ibm.com>
+ */
+
+#ifndef DRI_DEBUG_H
+#define DRI_DEBUG_H
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#include "main/context.h"
+
+typedef struct __DRIutilversionRec2    __DRIutilversion2;
+
+struct dri_debug_control {
+    const char * string;
+    unsigned     flag;
+};
+
+/**
+ * Used to store a version which includes a major range instead of a single
+ * major version number.
+ */
+struct __DRIutilversionRec2 {
+    int    major_min;    /** min allowed Major version number. */
+    int    major_max;    /** max allowed Major version number. */
+    int    minor;        /**< Minor version number. */
+    int    patch;        /**< Patch-level. */
+};
+
+extern void
+__driUtilMessage(const char *f, ...);
+
+extern unsigned driParseDebugString( const char * debug,
+    const struct dri_debug_control * control );
+
+extern unsigned driGetRendererString( char * buffer,
+    const char * hardware_name, GLuint agp_mode );
+
+extern GLboolean driCheckDriDdxDrmVersions2(const char * driver_name,
+    const __DRIversion * driActual, const __DRIversion * driExpected,
+    const __DRIversion * ddxActual, const __DRIversion * ddxExpected,
+    const __DRIversion * drmActual, const __DRIversion * drmExpected);
+
+extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name,
+    const __DRIversion * driActual, const __DRIversion * driExpected,
+    const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected,
+    const __DRIversion * drmActual, const __DRIversion * drmExpected);
+
+extern GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
+					   GLint *x, GLint *y,
+					   GLsizei *width, GLsizei *height );
+
+struct __DRIconfigRec {
+    struct gl_config modes;
+};
+
+extern __DRIconfig **
+driCreateConfigs(GLenum fb_format, GLenum fb_type,
+		 const uint8_t * depth_bits, const uint8_t * stencil_bits,
+		 unsigned num_depth_stencil_bits,
+		 const GLenum * db_modes, unsigned num_db_modes,
+		 const uint8_t * msaa_samples, unsigned num_msaa_modes,
+		 GLboolean enable_accum);
+
+__DRIconfig **driConcatConfigs(__DRIconfig **a,
+			       __DRIconfig **b);
+
+int
+driGetConfigAttrib(const __DRIconfig *config,
+		   unsigned int attrib, unsigned int *value);
+int
+driIndexConfigAttrib(const __DRIconfig *config, int index,
+		     unsigned int *attrib, unsigned int *value);
+
+#endif /* DRI_DEBUG_H */
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index 719b406ec..6c94947a0 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -135,6 +135,9 @@ swrastFillInModes(__DRIscreen *psp,
     uint8_t stencil_bits_array[4];
     uint8_t msaa_samples_array[1];
 
+    (void) psp;
+    (void) have_back_buffer;
+
     depth_bits_array[0] = 0;
     depth_bits_array[1] = 0;
     depth_bits_array[2] = depth_bits;
@@ -215,6 +218,7 @@ static void
 dri_destroy_screen(__DRIscreen * sPriv)
 {
     TRACE;
+    (void) sPriv;
 }
 
 
@@ -278,6 +282,9 @@ swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
 
     TRACE;
 
+    (void) ctx;
+    (void) internalFormat;
+
     rb->Data = NULL;
     rb->Width = width;
     rb->Height = height;
@@ -376,6 +383,9 @@ dri_create_buffer(__DRIscreen * sPriv,
 
     TRACE;
 
+    (void) sPriv;
+    (void) isPixmap;
+
     drawable = CALLOC_STRUCT(dri_drawable);
     if (drawable == NULL)
 	goto drawable_fail;
@@ -537,6 +547,10 @@ viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
     struct gl_framebuffer *draw = ctx->WinSysDrawBuffer;
     struct gl_framebuffer *read = ctx->WinSysReadBuffer;
 
+    (void) x;
+    (void) y;
+    (void) w;
+    (void) h;
     swrast_check_and_update_window_size(ctx, draw);
     swrast_check_and_update_window_size(ctx, read);
 }
@@ -609,9 +623,6 @@ InitExtensionsES2(struct gl_context *ctx)
 {
    int i;
 
-   /* Can't use driInitExtensions() since it uses extensions from
-    * main/remap_helper.h when called the first time. */
-
    for (i = 0; es2_extensions[i]; i++)
       _mesa_enable_extension(ctx, es2_extensions[i]);
 }
@@ -681,8 +692,6 @@ dri_create_context(gl_api api,
         _mesa_enable_1_5_extensions(mesaCtx);
         _mesa_enable_2_0_extensions(mesaCtx);
         _mesa_enable_2_1_extensions(mesaCtx);
-
-        driInitExtensions( mesaCtx, NULL, GL_FALSE );
         break;
     case API_OPENGLES:
         _mesa_enable_1_3_extensions(mesaCtx);
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 1903a503c..9cec15b58 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -37,6 +37,8 @@
 #include "mfeatures.h"
 #include "mtypes.h"
 
+#define ALIGN(value, alignment)  (((value) + alignment - 1) & ~(alignment - 1))
+
 enum {
    DISABLE = 0,
    GL  = 1 << API_OPENGL,
@@ -769,11 +771,11 @@ get_extension_override( struct gl_context *ctx )
    if (env_const == NULL) {
       /* Return the empty string rather than NULL. This simplifies the logic
        * of client functions. */
-      return calloc(1, sizeof(char));
+      return calloc(4, sizeof(char));
    }
 
    /* extra_exts: List of unrecognized extensions. */
-   extra_exts = calloc(strlen(env_const), sizeof(char));
+   extra_exts = calloc(ALIGN(strlen(env_const) + 2, 4), sizeof(char));
 
    /* Copy env_const because strtok() is destructive. */
    env = strdup(env_const);
@@ -907,7 +909,7 @@ _mesa_make_extension_string(struct gl_context *ctx)
    if (extra_extensions != NULL)
       length += 1 + strlen(extra_extensions); /* +1 for space */
 
-   exts = (char *) calloc(length + 1, sizeof(char));
+   exts = (char *) calloc(ALIGN(length + 1, 4), sizeof(char));
    if (exts == NULL) {
       free(extra_extensions);
       return NULL;
diff --git a/mesalib/src/mesa/main/nvprogram.c b/mesalib/src/mesa/main/nvprogram.c
index 7ff7645b7..a0e89b10f 100644
--- a/mesalib/src/mesa/main/nvprogram.c
+++ b/mesalib/src/mesa/main/nvprogram.c
@@ -560,7 +560,7 @@ _mesa_emit_nv_temp_initialization(struct gl_context *ctx,
 }
 
 void
-_mesa_setup_nv_temporary_count(struct gl_context *ctx, struct gl_program *program)
+_mesa_setup_nv_temporary_count(struct gl_program *program)
 {
    GLuint i;
 
diff --git a/mesalib/src/mesa/main/nvprogram.h b/mesalib/src/mesa/main/nvprogram.h
index 3d12b4e33..fc579a9fe 100644
--- a/mesalib/src/mesa/main/nvprogram.h
+++ b/mesalib/src/mesa/main/nvprogram.h
@@ -1,119 +1,119 @@
-/*
- * Mesa 3-D graphics library
- * Version:  5.1
- *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Brian Paul
- */
-
-
-#ifndef NVPROGRAM_H
-#define NVPROGRAM_H
-
-#include "glheader.h"
-
-struct gl_context;
-struct gl_program;
-
-extern void GLAPIENTRY
-_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params);
-
-extern GLboolean GLAPIENTRY 
-_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences);
-
-extern void GLAPIENTRY
-_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids);
-
-extern void GLAPIENTRY
-_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program);
-
-extern void GLAPIENTRY
-_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer);
-
-extern void GLAPIENTRY
-_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program);
-
-extern void GLAPIENTRY
-_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLsizei num,
-                             const GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLsizei num,
-                             const GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
-                                GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                 const float v[]);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
-                                GLdouble x, GLdouble y, GLdouble z, GLdouble w);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                 const double v[]);
-
-extern void GLAPIENTRY
-_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                   GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                   GLdouble *params);
-
-extern void
-_mesa_setup_nv_temporary_count(struct gl_context *ctx, struct gl_program *program);
-
-extern void
-_mesa_emit_nv_temp_initialization(struct gl_context *ctx,
-				  struct gl_program *program);
-
-#endif
+/*
+ * Mesa 3-D graphics library
+ * Version:  5.1
+ *
+ * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Brian Paul
+ */
+
+
+#ifndef NVPROGRAM_H
+#define NVPROGRAM_H
+
+#include "glheader.h"
+
+struct gl_context;
+struct gl_program;
+
+extern void GLAPIENTRY
+_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params);
+
+extern GLboolean GLAPIENTRY 
+_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences);
+
+extern void GLAPIENTRY
+_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids);
+
+extern void GLAPIENTRY
+_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program);
+
+extern void GLAPIENTRY
+_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer);
+
+extern void GLAPIENTRY
+_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+
+extern void GLAPIENTRY
+_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLsizei num,
+                             const GLdouble *params);
+
+extern void GLAPIENTRY
+_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLsizei num,
+                             const GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
+                                GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                 const float v[]);
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
+                                GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                 const double v[]);
+
+extern void GLAPIENTRY
+_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                   GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                   GLdouble *params);
+
+extern void
+_mesa_setup_nv_temporary_count(struct gl_program *program);
+
+extern void
+_mesa_emit_nv_temp_initialization(struct gl_context *ctx,
+				  struct gl_program *program);
+
+#endif
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index b59961eaf..8ef1d4560 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -1,285 +1,286 @@
-/**
- * \file teximage.h
- * Texture images manipulation functions.
- */
-
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef TEXIMAGE_H
-#define TEXIMAGE_H
-
-
-#include "mtypes.h"
-#include "formats.h"
-
-
-extern void *
-_mesa_alloc_texmemory(GLsizei bytes);
-
-extern void
-_mesa_free_texmemory(void *m);
-
-
-/** \name Internal functions */
-/*@{*/
-
-extern GLint
-_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat );
-
-
-extern GLboolean
-_mesa_is_proxy_texture(GLenum target);
-
-
-extern struct gl_texture_image *
-_mesa_new_texture_image( struct gl_context *ctx );
-
-
-extern void
-_mesa_delete_texture_image( struct gl_context *ctx,
-                            struct gl_texture_image *teximage );
-
-extern void
-_mesa_free_texture_image_data( struct gl_context *ctx, 
-			       struct gl_texture_image *texImage );
-
-
-extern void
-_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
-                           struct gl_texture_image *img,
-                           GLsizei width, GLsizei height, GLsizei depth,
-                           GLint border, GLenum internalFormat,
-                           gl_format format);
-
-
-extern gl_format
-_mesa_choose_texture_format(struct gl_context *ctx,
-                            struct gl_texture_object *texObj,
-                            GLenum target, GLint level,
-                            GLenum internalFormat, GLenum format, GLenum type);
-
-
-extern void
-_mesa_clear_texture_image(struct gl_context *ctx,
-                          struct gl_texture_image *texImage);
-
-
-extern void
-_mesa_set_tex_image(struct gl_texture_object *tObj,
-                    GLenum target, GLint level,
-                    struct gl_texture_image *texImage);
-
-
-extern struct gl_texture_object *
-_mesa_select_tex_object(struct gl_context *ctx,
-                        const struct gl_texture_unit *texUnit,
-                        GLenum target);
-
-extern struct gl_texture_object *
-_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target);
-
-
-extern struct gl_texture_image *
-_mesa_select_tex_image(struct gl_context *ctx,
-                       const struct gl_texture_object *texObj,
-                       GLenum target, GLint level);
-
-
-extern struct gl_texture_image *
-_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
-                    GLenum target, GLint level);
-
-
-extern struct gl_texture_image *
-_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level);
-
-
-extern GLint
-_mesa_max_texture_levels(struct gl_context *ctx, GLenum target);
-
-
-extern GLboolean
-_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
-                         GLint internalFormat, GLenum format, GLenum type,
-                         GLint width, GLint height, GLint depth, GLint border);
-
-
-extern GLuint
-_mesa_tex_target_to_face(GLenum target);
-
-extern GLint
-_mesa_get_texture_dimensions(GLenum target);
-
-/**
- * Lock a texture for updating.  See also _mesa_lock_context_textures().
- */
-static INLINE void
-_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
-   _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
-   ctx->Shared->TextureStateStamp++;
-   (void) texObj;
-}
-
-static INLINE void
-_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
-   _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
-}
-
-/*@}*/
-
-
-/** \name API entry point functions */
-/*@{*/
-
-extern void GLAPIENTRY
-_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
-                  GLsizei width, GLint border,
-                  GLenum format, GLenum type, const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
-                  GLsizei width, GLsizei height, GLint border,
-                  GLenum format, GLenum type, const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
-                  GLsizei width, GLsizei height, GLsizei depth, GLint border,
-                  GLenum format, GLenum type, const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
-                     GLsizei width, GLsizei height, GLsizei depth,
-                     GLint border, GLenum format, GLenum type,
-                     const GLvoid *pixels );
-
-extern void GLAPIENTRY
-_mesa_EGLImageTargetTexture2DOES( GLenum target, GLeglImageOES image );
-
-extern void GLAPIENTRY
-_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
-                     GLsizei width,
-                     GLenum format, GLenum type,
-                     const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexSubImage2D( GLenum target, GLint level,
-                     GLint xoffset, GLint yoffset,
-                     GLsizei width, GLsizei height,
-                     GLenum format, GLenum type,
-                     const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexSubImage3D( GLenum target, GLint level,
-                     GLint xoffset, GLint yoffset, GLint zoffset,
-                     GLsizei width, GLsizei height, GLsizei depth,
-                     GLenum format, GLenum type,
-                     const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat,
-                      GLint x, GLint y, GLsizei width, GLint border );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexImage2D( GLenum target, GLint level,
-                      GLenum internalformat, GLint x, GLint y,
-                      GLsizei width, GLsizei height, GLint border );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset,
-                         GLint x, GLint y, GLsizei width );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexSubImage2D( GLenum target, GLint level,
-                         GLint xoffset, GLint yoffset,
-                         GLint x, GLint y, GLsizei width, GLsizei height );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexSubImage3D( GLenum target, GLint level,
-                         GLint xoffset, GLint yoffset, GLint zoffset,
-                         GLint x, GLint y, GLsizei width, GLsizei height );
-
-
-
-extern void GLAPIENTRY
-_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
-                              GLenum internalformat, GLsizei width,
-                              GLint border, GLsizei imageSize,
-                              const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
-                              GLenum internalformat, GLsizei width,
-                              GLsizei height, GLint border, GLsizei imageSize,
-                              const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
-                              GLenum internalformat, GLsizei width,
-                              GLsizei height, GLsizei depth, GLint border,
-                              GLsizei imageSize, const GLvoid *data);
-
-#ifdef VMS
-#define _mesa_CompressedTexSubImage1DARB _mesa_CompressedTexSubImage1DAR
-#define _mesa_CompressedTexSubImage2DARB _mesa_CompressedTexSubImage2DAR
-#define _mesa_CompressedTexSubImage3DARB _mesa_CompressedTexSubImage3DAR
-#endif
-extern void GLAPIENTRY
-_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
-                                 GLsizei width, GLenum format,
-                                 GLsizei imageSize, const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
-                                 GLint yoffset, GLsizei width, GLsizei height,
-                                 GLenum format, GLsizei imageSize,
-                                 const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
-                                 GLint yoffset, GLint zoffset, GLsizei width,
-                                 GLsizei height, GLsizei depth, GLenum format,
-                                 GLsizei imageSize, const GLvoid *data);
-
-
-extern void GLAPIENTRY
-_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer);
-
-
-/*@}*/
-
-#endif
+/**
+ * \file teximage.h
+ * Texture images manipulation functions.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef TEXIMAGE_H
+#define TEXIMAGE_H
+
+
+#include "mtypes.h"
+#include "formats.h"
+
+
+extern void *
+_mesa_alloc_texmemory(GLsizei bytes);
+
+extern void
+_mesa_free_texmemory(void *m);
+
+
+/** \name Internal functions */
+/*@{*/
+
+extern GLint
+_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat );
+
+
+extern GLboolean
+_mesa_is_proxy_texture(GLenum target);
+
+
+extern struct gl_texture_image *
+_mesa_new_texture_image( struct gl_context *ctx );
+
+
+extern void
+_mesa_delete_texture_image( struct gl_context *ctx,
+                            struct gl_texture_image *teximage );
+
+extern void
+_mesa_free_texture_image_data( struct gl_context *ctx, 
+			       struct gl_texture_image *texImage );
+
+
+extern void
+_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
+                           struct gl_texture_image *img,
+                           GLsizei width, GLsizei height, GLsizei depth,
+                           GLint border, GLenum internalFormat,
+                           gl_format format);
+
+
+extern gl_format
+_mesa_choose_texture_format(struct gl_context *ctx,
+                            struct gl_texture_object *texObj,
+                            GLenum target, GLint level,
+                            GLenum internalFormat, GLenum format, GLenum type);
+
+
+extern void
+_mesa_clear_texture_image(struct gl_context *ctx,
+                          struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_set_tex_image(struct gl_texture_object *tObj,
+                    GLenum target, GLint level,
+                    struct gl_texture_image *texImage);
+
+
+extern struct gl_texture_object *
+_mesa_select_tex_object(struct gl_context *ctx,
+                        const struct gl_texture_unit *texUnit,
+                        GLenum target);
+
+extern struct gl_texture_object *
+_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target);
+
+
+extern struct gl_texture_image *
+_mesa_select_tex_image(struct gl_context *ctx,
+                       const struct gl_texture_object *texObj,
+                       GLenum target, GLint level);
+
+
+extern struct gl_texture_image *
+_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
+                    GLenum target, GLint level);
+
+
+extern struct gl_texture_image *
+_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level);
+
+
+extern GLint
+_mesa_max_texture_levels(struct gl_context *ctx, GLenum target);
+
+
+extern GLboolean
+_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
+                         GLint internalFormat, GLenum format, GLenum type,
+                         GLint width, GLint height, GLint depth, GLint border);
+
+
+extern GLuint
+_mesa_tex_target_to_face(GLenum target);
+
+extern GLint
+_mesa_get_texture_dimensions(GLenum target);
+
+/**
+ * Lock a texture for updating.  See also _mesa_lock_context_textures().
+ */
+static INLINE void
+_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+   _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
+   ctx->Shared->TextureStateStamp++;
+   (void) texObj;
+}
+
+static INLINE void
+_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+   (void) texObj;
+   _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
+}
+
+/*@}*/
+
+
+/** \name API entry point functions */
+/*@{*/
+
+extern void GLAPIENTRY
+_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
+                  GLsizei width, GLint border,
+                  GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
+                  GLsizei width, GLsizei height, GLint border,
+                  GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
+                  GLsizei width, GLsizei height, GLsizei depth, GLint border,
+                  GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
+                     GLsizei width, GLsizei height, GLsizei depth,
+                     GLint border, GLenum format, GLenum type,
+                     const GLvoid *pixels );
+
+extern void GLAPIENTRY
+_mesa_EGLImageTargetTexture2DOES( GLenum target, GLeglImageOES image );
+
+extern void GLAPIENTRY
+_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
+                     GLsizei width,
+                     GLenum format, GLenum type,
+                     const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexSubImage2D( GLenum target, GLint level,
+                     GLint xoffset, GLint yoffset,
+                     GLsizei width, GLsizei height,
+                     GLenum format, GLenum type,
+                     const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexSubImage3D( GLenum target, GLint level,
+                     GLint xoffset, GLint yoffset, GLint zoffset,
+                     GLsizei width, GLsizei height, GLsizei depth,
+                     GLenum format, GLenum type,
+                     const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat,
+                      GLint x, GLint y, GLsizei width, GLint border );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexImage2D( GLenum target, GLint level,
+                      GLenum internalformat, GLint x, GLint y,
+                      GLsizei width, GLsizei height, GLint border );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset,
+                         GLint x, GLint y, GLsizei width );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexSubImage2D( GLenum target, GLint level,
+                         GLint xoffset, GLint yoffset,
+                         GLint x, GLint y, GLsizei width, GLsizei height );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexSubImage3D( GLenum target, GLint level,
+                         GLint xoffset, GLint yoffset, GLint zoffset,
+                         GLint x, GLint y, GLsizei width, GLsizei height );
+
+
+
+extern void GLAPIENTRY
+_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
+                              GLenum internalformat, GLsizei width,
+                              GLint border, GLsizei imageSize,
+                              const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
+                              GLenum internalformat, GLsizei width,
+                              GLsizei height, GLint border, GLsizei imageSize,
+                              const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
+                              GLenum internalformat, GLsizei width,
+                              GLsizei height, GLsizei depth, GLint border,
+                              GLsizei imageSize, const GLvoid *data);
+
+#ifdef VMS
+#define _mesa_CompressedTexSubImage1DARB _mesa_CompressedTexSubImage1DAR
+#define _mesa_CompressedTexSubImage2DARB _mesa_CompressedTexSubImage2DAR
+#define _mesa_CompressedTexSubImage3DARB _mesa_CompressedTexSubImage3DAR
+#endif
+extern void GLAPIENTRY
+_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
+                                 GLsizei width, GLenum format,
+                                 GLsizei imageSize, const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
+                                 GLint yoffset, GLsizei width, GLsizei height,
+                                 GLenum format, GLsizei imageSize,
+                                 const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
+                                 GLint yoffset, GLint zoffset, GLsizei width,
+                                 GLsizei height, GLsizei depth, GLenum format,
+                                 GLsizei imageSize, const GLvoid *data);
+
+
+extern void GLAPIENTRY
+_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer);
+
+
+/*@}*/
+
+#endif
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 9813c4ae8..69a84de39 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -2156,6 +2156,8 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
       break;
    }
 
+   const glsl_type *sampler_type = ir->sampler->type;
+
    if (ir->projector) {
       if (opcode == OPCODE_TEX) {
 	 /* Slot the projector in as the last component of the coord. */
@@ -2187,6 +2189,9 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
 	    tmp_src = get_temp(glsl_type::vec4_type);
 	    dst_reg tmp_dst = dst_reg(tmp_src);
 
+	    /* Projective division not allowed for array samplers. */
+	    assert(!sampler_type->sampler_array);
+
 	    tmp_dst.writemask = WRITEMASK_Z;
 	    emit(ir, OPCODE_MOV, tmp_dst, this->result);
 
@@ -2211,7 +2216,15 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
        * coord.
        */
       ir->shadow_comparitor->accept(this);
-      coord_dst.writemask = WRITEMASK_Z;
+
+      /* XXX This will need to be updated for cubemap array samplers. */
+      if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
+          sampler_type->sampler_array) {
+         coord_dst.writemask = WRITEMASK_W;
+      } else {
+         coord_dst.writemask = WRITEMASK_Z;
+      }
+
       emit(ir, OPCODE_MOV, coord_dst, this->result);
       coord_dst.writemask = WRITEMASK_XYZW;
    }
@@ -2235,8 +2248,6 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
 						   this->shader_program,
 						   this->prog);
 
-   const glsl_type *sampler_type = ir->sampler->type;
-
    switch (sampler_type->sampler_dimensionality) {
    case GLSL_SAMPLER_DIM_1D:
       inst->tex_target = (sampler_type->sampler_array)
diff --git a/mesalib/src/mesa/program/nvvertparse.c b/mesalib/src/mesa/program/nvvertparse.c
index 8f7199a99..91fe2c48b 100644
--- a/mesalib/src/mesa/program/nvvertparse.c
+++ b/mesalib/src/mesa/program/nvvertparse.c
@@ -1,1459 +1,1459 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.2
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file nvvertparse.c
- * NVIDIA vertex program parser.
- * \author Brian Paul
- */
-
-/*
- * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1:
- *
- * Portions of this software may use or implement intellectual
- * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
- * any and all warranties with respect to such intellectual property,
- * including any use thereof or modifications thereto.
- */
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/imports.h"
-#include "main/nvprogram.h"
-#include "nvvertparse.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "program.h"
-
-
-/**
- * Current parsing state.  This structure is passed among the parsing
- * functions and keeps track of the current parser position and various
- * program attributes.
- */
-struct parse_state {
-   struct gl_context *ctx;
-   const GLubyte *start;
-   const GLubyte *pos;
-   const GLubyte *curLine;
-   GLboolean isStateProgram;
-   GLboolean isPositionInvariant;
-   GLboolean isVersion1_1;
-   GLbitfield inputsRead;
-   GLbitfield outputsWritten;
-   GLboolean anyProgRegsWritten;
-   GLboolean indirectRegisterFiles;
-   GLuint numInst;                 /* number of instructions parsed */
-};
-
-
-/*
- * Called whenever we find an error during parsing.
- */
-static void
-record_error(struct parse_state *parseState, const char *msg, int lineNo)
-{
-#ifdef DEBUG
-   GLint line, column;
-   const GLubyte *lineStr;
-   lineStr = _mesa_find_line_column(parseState->start,
-                                    parseState->pos, &line, &column);
-   _mesa_debug(parseState->ctx,
-               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
-               lineNo, line, column, (char *) lineStr, msg);
-   free((void *) lineStr);
-#else
-   (void) lineNo;
-#endif
-
-   /* Check that no error was already recorded.  Only record the first one. */
-   if (parseState->ctx->Program.ErrorString[0] == 0) {
-      _mesa_set_program_error(parseState->ctx,
-                              parseState->pos - parseState->start,
-                              msg);
-   }
-}
-
-
-#define RETURN_ERROR							\
-do {									\
-   record_error(parseState, "Unexpected end of input.", __LINE__);	\
-   return GL_FALSE;							\
-} while(0)
-
-#define RETURN_ERROR1(msg)						\
-do {									\
-   record_error(parseState, msg, __LINE__);				\
-   return GL_FALSE;							\
-} while(0)
-
-#define RETURN_ERROR2(msg1, msg2)					\
-do {									\
-   char err[1000];							\
-   sprintf(err, "%s %s", msg1, msg2);				\
-   record_error(parseState, err, __LINE__);				\
-   return GL_FALSE;							\
-} while(0)
-
-
-
-
-
-static GLboolean IsLetter(GLubyte b)
-{
-   return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z');
-}
-
-
-static GLboolean IsDigit(GLubyte b)
-{
-   return b >= '0' && b <= '9';
-}
-
-
-static GLboolean IsWhitespace(GLubyte b)
-{
-   return b == ' ' || b == '\t' || b == '\n' || b == '\r';
-}
-
-
-/**
- * Starting at 'str' find the next token.  A token can be an integer,
- * an identifier or punctuation symbol.
- * \return <= 0 we found an error, else, return number of characters parsed.
- */
-static GLint
-GetToken(struct parse_state *parseState, GLubyte *token)
-{
-   const GLubyte *str = parseState->pos;
-   GLint i = 0, j = 0;
-
-   token[0] = 0;
-
-   /* skip whitespace and comments */
-   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
-      if (str[i] == '#') {
-         /* skip comment */
-         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
-            i++;
-         }
-         if (str[i] == '\n' || str[i] == '\r')
-            parseState->curLine = str + i + 1;
-      }
-      else {
-         /* skip whitespace */
-         if (str[i] == '\n' || str[i] == '\r')
-            parseState->curLine = str + i + 1;
-         i++;
-      }
-   }
-
-   if (str[i] == 0)
-      return -i;
-
-   /* try matching an integer */
-   while (str[i] && IsDigit(str[i])) {
-      token[j++] = str[i++];
-   }
-   if (j > 0 || !str[i]) {
-      token[j] = 0;
-      return i;
-   }
-
-   /* try matching an identifier */
-   if (IsLetter(str[i])) {
-      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
-         token[j++] = str[i++];
-      }
-      token[j] = 0;
-      return i;
-   }
-
-   /* punctuation character */
-   if (str[i]) {
-      token[0] = str[i++];
-      token[1] = 0;
-      return i;
-   }
-
-   /* end of input */
-   token[0] = 0;
-   return i;
-}
-
-
-/**
- * Get next token from input stream and increment stream pointer past token.
- */
-static GLboolean
-Parse_Token(struct parse_state *parseState, GLubyte *token)
-{
-   GLint i;
-   i = GetToken(parseState, token);
-   if (i <= 0) {
-      parseState->pos += (-i);
-      return GL_FALSE;
-   }
-   parseState->pos += i;
-   return GL_TRUE;
-}
-
-
-/**
- * Get next token from input stream but don't increment stream pointer.
- */
-static GLboolean
-Peek_Token(struct parse_state *parseState, GLubyte *token)
-{
-   GLint i, len;
-   i = GetToken(parseState, token);
-   if (i <= 0) {
-      parseState->pos += (-i);
-      return GL_FALSE;
-   }
-   len = (GLint) strlen((const char *) token);
-   parseState->pos += (i - len);
-   return GL_TRUE;
-}
-
-
-/**
- * Try to match 'pattern' as the next token after any whitespace/comments.
- * Advance the current parsing position only if we match the pattern.
- * \return GL_TRUE if pattern is matched, GL_FALSE otherwise.
- */
-static GLboolean
-Parse_String(struct parse_state *parseState, const char *pattern)
-{
-   const GLubyte *m;
-   GLint i;
-
-   /* skip whitespace and comments */
-   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
-      if (*parseState->pos == '#') {
-         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
-            parseState->pos += 1;
-         }
-         if (*parseState->pos == '\n' || *parseState->pos == '\r')
-            parseState->curLine = parseState->pos + 1;
-      }
-      else {
-         /* skip whitespace */
-         if (*parseState->pos == '\n' || *parseState->pos == '\r')
-            parseState->curLine = parseState->pos + 1;
-         parseState->pos += 1;
-      }
-   }
-
-   /* Try to match the pattern */
-   m = parseState->pos;
-   for (i = 0; pattern[i]; i++) {
-      if (*m != (GLubyte) pattern[i])
-         return GL_FALSE;
-      m += 1;
-   }
-   parseState->pos = m;
-
-   return GL_TRUE; /* success */
-}
-
-
-/**********************************************************************/
-
-static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = {
-   "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7",
-   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
-};
-
-static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
-   "HPOS", "COL0", "COL1", "FOGC", 
-   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", 
-   "PSIZ", "BFC0", "BFC1", NULL
-};
-
-
-
-/**
- * Parse a temporary register: Rnn
- */
-static GLboolean
-Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
-{
-   GLubyte token[100];
-
-   /* Should be 'R##' */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] != 'R')
-      RETURN_ERROR1("Expected R##");
-
-   if (IsDigit(token[1])) {
-      GLint reg = atoi((char *) (token + 1));
-      if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS)
-         RETURN_ERROR1("Bad temporary register name");
-      *tempRegNum = reg;
-   }
-   else {
-      RETURN_ERROR1("Bad temporary register name");
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse address register "A0.x"
- */
-static GLboolean
-Parse_AddrReg(struct parse_state *parseState)
-{
-   /* match 'A0' */
-   if (!Parse_String(parseState, "A0"))
-      RETURN_ERROR;
-
-   /* match '.' */
-   if (!Parse_String(parseState, "."))
-      RETURN_ERROR;
-
-   /* match 'x' */
-   if (!Parse_String(parseState, "x"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse absolute program parameter register "c[##]"
- */
-static GLboolean
-Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum)
-{
-   GLubyte token[100];
-
-   if (!Parse_String(parseState, "c"))
-      RETURN_ERROR;
-
-   if (!Parse_String(parseState, "["))
-      RETURN_ERROR;
-
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (IsDigit(token[0])) {
-      /* a numbered program parameter register */
-      GLint reg = atoi((char *) token);
-      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
-         RETURN_ERROR1("Bad program parameter number");
-      *regNum = reg;
-   }
-   else {
-      RETURN_ERROR;
-   }
-
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
-   GLubyte token[100];
-
-   if (!Parse_String(parseState, "c"))
-      RETURN_ERROR;
-
-   if (!Parse_String(parseState, "["))
-      RETURN_ERROR;
-
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (IsDigit(token[0])) {
-      /* a numbered program parameter register */
-      GLint reg;
-      (void) Parse_Token(parseState, token);
-      reg = atoi((char *) token);
-      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
-         RETURN_ERROR1("Bad program parameter number");
-      srcReg->File = PROGRAM_ENV_PARAM;
-      srcReg->Index = reg;
-   }
-   else if (strcmp((const char *) token, "A0") == 0) {
-      /* address register "A0.x" */
-      if (!Parse_AddrReg(parseState))
-         RETURN_ERROR;
-
-      srcReg->RelAddr = GL_TRUE;
-      srcReg->File = PROGRAM_ENV_PARAM;
-      parseState->indirectRegisterFiles |= (1 << srcReg->File);
-      /* Look for +/-N offset */
-      if (!Peek_Token(parseState, token))
-         RETURN_ERROR;
-
-      if (token[0] == '-' || token[0] == '+') {
-         const GLubyte sign = token[0];
-         (void) Parse_Token(parseState, token); /* consume +/- */
-
-         /* an integer should be next */
-         if (!Parse_Token(parseState, token))
-            RETURN_ERROR;
-
-         if (IsDigit(token[0])) {
-            const GLint k = atoi((char *) token);
-            if (sign == '-') {
-               if (k > 64)
-                  RETURN_ERROR1("Bad address offset");
-               srcReg->Index = -k;
-            }
-            else {
-               if (k > 63)
-                  RETURN_ERROR1("Bad address offset");
-               srcReg->Index = k;
-            }
-         }
-         else {
-            RETURN_ERROR;
-         }
-      }
-      else {
-         /* probably got a ']', catch it below */
-      }
-   }
-   else {
-      RETURN_ERROR;
-   }
-
-   /* Match closing ']' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse v[#] or v[<name>]
- */
-static GLboolean
-Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum)
-{
-   GLubyte token[100];
-   GLint j;
-
-   /* Match 'v' */
-   if (!Parse_String(parseState, "v"))
-      RETURN_ERROR;
-
-   /* Match '[' */
-   if (!Parse_String(parseState, "["))
-      RETURN_ERROR;
-
-   /* match number or named register */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (parseState->isStateProgram && token[0] != '0')
-      RETURN_ERROR1("Only v[0] accessible in vertex state programs");
-
-   if (IsDigit(token[0])) {
-      GLint reg = atoi((char *) token);
-      if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS)
-         RETURN_ERROR1("Bad vertex attribute register name");
-      *tempRegNum = reg;
-   }
-   else {
-      for (j = 0; InputRegisters[j]; j++) {
-         if (strcmp((const char *) token, InputRegisters[j]) == 0) {
-            *tempRegNum = j;
-            break;
-         }
-      }
-      if (!InputRegisters[j]) {
-         /* unknown input register label */
-         RETURN_ERROR2("Bad register name", token);
-      }
-   }
-
-   /* Match '[' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
-{
-   GLubyte token[100];
-   GLint start, j;
-
-   /* Match 'o' */
-   if (!Parse_String(parseState, "o"))
-      RETURN_ERROR;
-
-   /* Match '[' */
-   if (!Parse_String(parseState, "["))
-      RETURN_ERROR;
-
-   /* Get output reg name */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (parseState->isPositionInvariant)
-      start = 1; /* skip HPOS register name */
-   else
-      start = 0;
-
-   /* try to match an output register name */
-   for (j = start; OutputRegisters[j]; j++) {
-      if (strcmp((const char *) token, OutputRegisters[j]) == 0) {
-         *outputRegNum = j;
-         break;
-      }
-   }
-   if (!OutputRegisters[j])
-      RETURN_ERROR1("Unrecognized output register name");
-
-   /* Match ']' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR1("Expected ]");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg)
-{
-   GLubyte token[100];
-   GLint idx;
-
-   /* Dst reg can be R<n> or o[n] */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (token[0] == 'R') {
-      /* a temporary register */
-      dstReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else if (!parseState->isStateProgram && token[0] == 'o') {
-      /* an output register */
-      dstReg->File = PROGRAM_OUTPUT;
-      if (!Parse_OutputReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else if (parseState->isStateProgram && token[0] == 'c' &&
-            parseState->isStateProgram) {
-      /* absolute program parameter register */
-      /* Only valid for vertex state programs */
-      dstReg->File = PROGRAM_ENV_PARAM;
-      if (!Parse_AbsParamReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else {
-      RETURN_ERROR1("Bad destination register name");
-   }
-
-   /* Parse optional write mask */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (token[0] == '.') {
-      /* got a mask */
-      GLint k = 0;
-
-      if (!Parse_String(parseState, "."))
-         RETURN_ERROR;
-
-      if (!Parse_Token(parseState, token))
-         RETURN_ERROR;
-
-      dstReg->WriteMask = 0;
-
-      if (token[k] == 'x') {
-         dstReg->WriteMask |= WRITEMASK_X;
-         k++;
-      }
-      if (token[k] == 'y') {
-         dstReg->WriteMask |= WRITEMASK_Y;
-         k++;
-      }
-      if (token[k] == 'z') {
-         dstReg->WriteMask |= WRITEMASK_Z;
-         k++;
-      }
-      if (token[k] == 'w') {
-         dstReg->WriteMask |= WRITEMASK_W;
-         k++;
-      }
-      if (k == 0) {
-         RETURN_ERROR1("Bad writemask character");
-      }
-      return GL_TRUE;
-   }
-   else {
-      dstReg->WriteMask = WRITEMASK_XYZW;
-      return GL_TRUE;
-   }
-}
-
-
-static GLboolean
-Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
-   GLubyte token[100];
-   GLint idx;
-
-   srcReg->RelAddr = GL_FALSE;
-
-   /* check for '-' */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] == '-') {
-      (void) Parse_String(parseState, "-");
-      srcReg->Negate = NEGATE_XYZW;
-      if (!Peek_Token(parseState, token))
-         RETURN_ERROR;
-   }
-   else {
-      srcReg->Negate = NEGATE_NONE;
-   }
-
-   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
-   if (token[0] == 'R') {
-      srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'c') {
-      if (!Parse_ParamReg(parseState, srcReg))
-         RETURN_ERROR;
-   }
-   else if (token[0] == 'v') {
-      srcReg->File = PROGRAM_INPUT;
-      if (!Parse_AttribReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else {
-      RETURN_ERROR2("Bad source register name", token);
-   }
-
-   /* init swizzle fields */
-   srcReg->Swizzle = SWIZZLE_NOOP;
-
-   /* Look for optional swizzle suffix */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] == '.') {
-      (void) Parse_String(parseState, ".");  /* consume . */
-
-      if (!Parse_Token(parseState, token))
-         RETURN_ERROR;
-
-      if (token[1] == 0) {
-         /* single letter swizzle */
-         if (token[0] == 'x')
-            srcReg->Swizzle = SWIZZLE_XXXX;
-         else if (token[0] == 'y')
-            srcReg->Swizzle = SWIZZLE_YYYY;
-         else if (token[0] == 'z')
-            srcReg->Swizzle = SWIZZLE_ZZZZ;
-         else if (token[0] == 'w')
-            srcReg->Swizzle = SWIZZLE_WWWW;
-         else
-            RETURN_ERROR1("Expected x, y, z, or w");
-      }
-      else {
-         /* 2, 3 or 4-component swizzle */
-         GLint k;
-
-         srcReg->Swizzle = 0;
-
-         for (k = 0; token[k] && k < 5; k++) {
-            if (token[k] == 'x')
-               srcReg->Swizzle |= 0 << (k*3);
-            else if (token[k] == 'y')
-               srcReg->Swizzle |= 1 << (k*3);
-            else if (token[k] == 'z')
-               srcReg->Swizzle |= 2 << (k*3);
-            else if (token[k] == 'w')
-               srcReg->Swizzle |= 3 << (k*3);
-            else
-               RETURN_ERROR;
-         }
-         if (k >= 5)
-            RETURN_ERROR;
-      }
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
-   GLubyte token[100];
-   GLint idx;
-
-   srcReg->RelAddr = GL_FALSE;
-
-   /* check for '-' */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] == '-') {
-      srcReg->Negate = NEGATE_XYZW;
-      (void) Parse_String(parseState, "-"); /* consume '-' */
-      if (!Peek_Token(parseState, token))
-         RETURN_ERROR;
-   }
-   else {
-      srcReg->Negate = NEGATE_NONE;
-   }
-
-   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
-   if (token[0] == 'R') {
-      srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'c') {
-      if (!Parse_ParamReg(parseState, srcReg))
-         RETURN_ERROR;
-   }
-   else if (token[0] == 'v') {
-      srcReg->File = PROGRAM_INPUT;
-      if (!Parse_AttribReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else {
-      RETURN_ERROR2("Bad source register name", token);
-   }
-
-   /* Look for .[xyzw] suffix */
-   if (!Parse_String(parseState, "."))
-      RETURN_ERROR;
-
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (token[0] == 'x' && token[1] == 0) {
-      srcReg->Swizzle = 0;
-   }
-   else if (token[0] == 'y' && token[1] == 0) {
-      srcReg->Swizzle = 1;
-   }
-   else if (token[0] == 'z' && token[1] == 0) {
-      srcReg->Swizzle = 2;
-   }
-   else if (token[0] == 'w' && token[1] == 0) {
-      srcReg->Swizzle = 3;
-   }
-   else {
-      RETURN_ERROR1("Bad scalar source suffix");
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLint
-Parse_UnaryOpInstruction(struct parse_state *parseState,
-                         struct prog_instruction *inst,
-                         enum prog_opcode opcode)
-{
-   if (opcode == OPCODE_ABS && !parseState->isVersion1_1)
-      RETURN_ERROR1("ABS illegal for vertex program 1.0");
-
-   inst->Opcode = opcode;
-
-   /* dest reg */
-   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_BiOpInstruction(struct parse_state *parseState,
-                      struct prog_instruction *inst,
-                      enum prog_opcode opcode)
-{
-   if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
-      RETURN_ERROR1("DPH illegal for vertex program 1.0");
-   if (opcode == OPCODE_SUB && !parseState->isVersion1_1)
-      RETURN_ERROR1("SUB illegal for vertex program 1.0");
-
-   inst->Opcode = opcode;
-
-   /* dest reg */
-   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* first src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* second src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   /* make sure we don't reference more than one program parameter register */
-   if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
-       inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
-       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
-      RETURN_ERROR1("Can't reference two program parameter registers");
-
-   /* make sure we don't reference more than one vertex attribute register */
-   if (inst->SrcReg[0].File == PROGRAM_INPUT &&
-       inst->SrcReg[1].File == PROGRAM_INPUT &&
-       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
-      RETURN_ERROR1("Can't reference two vertex attribute registers");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_TriOpInstruction(struct parse_state *parseState,
-                       struct prog_instruction *inst,
-                       enum prog_opcode opcode)
-{
-   inst->Opcode = opcode;
-
-   /* dest reg */
-   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* first src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* second src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* third src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   /* make sure we don't reference more than one program parameter register */
-   if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
-       (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
-       (inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
-      RETURN_ERROR1("Can only reference one program register");
-
-   /* make sure we don't reference more than one vertex attribute register */
-   if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
-        inst->SrcReg[1].File == PROGRAM_INPUT &&
-        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
-       (inst->SrcReg[0].File == PROGRAM_INPUT &&
-        inst->SrcReg[2].File == PROGRAM_INPUT &&
-        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
-       (inst->SrcReg[1].File == PROGRAM_INPUT &&
-        inst->SrcReg[2].File == PROGRAM_INPUT &&
-        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
-      RETURN_ERROR1("Can only reference one input register");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarInstruction(struct parse_state *parseState,
-                        struct prog_instruction *inst,
-                        enum prog_opcode opcode)
-{
-   if (opcode == OPCODE_RCC && !parseState->isVersion1_1)
-      RETURN_ERROR1("RCC illegal for vertex program 1.0");
-
-   inst->Opcode = opcode;
-
-   /* dest reg */
-   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* first src arg */
-   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
-   inst->Opcode = OPCODE_ARL;
-
-   /* Make ARB_vp backends happy */
-   inst->DstReg.File = PROGRAM_ADDRESS;
-   inst->DstReg.WriteMask = WRITEMASK_X;
-   inst->DstReg.Index = 0;
-
-   /* dest A0 reg */
-   if (!Parse_AddrReg(parseState))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* parse src reg */
-   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
-   GLubyte token[100];
-
-   inst->Opcode = OPCODE_END;
-
-   /* this should fail! */
-   if (Parse_Token(parseState, token))
-      RETURN_ERROR2("Unexpected token after END:", token);
-   else
-      return GL_TRUE;
-}
-
-
-/**
- * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
- * the vertex program developer.
- * The NV_vertex_program extension grammar is modified as follows:
- *
- *  <instruction>        ::= <ARL-instruction>
- *                         | ...
- *                         | <PRINT-instruction>
- *
- *  <PRINT-instruction>  ::= "PRINT" <string literal>
- *                         | "PRINT" <string literal> "," <srcReg>
- *                         | "PRINT" <string literal> "," <dstReg>
- */
-static GLboolean
-Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
-   const GLubyte *str;
-   GLubyte *msg;
-   GLuint len;
-   GLubyte token[100];
-   struct prog_src_register *srcReg = &inst->SrcReg[0];
-   GLint idx;
-
-   inst->Opcode = OPCODE_PRINT;
-
-   /* The first argument is a literal string 'just like this' */
-   if (!Parse_String(parseState, "'"))
-      RETURN_ERROR;
-
-   str = parseState->pos;
-   for (len = 0; str[len] != '\''; len++) /* find closing quote */
-      ;
-   parseState->pos += len + 1;
-   msg = (GLubyte*) malloc(len + 1);
-
-   memcpy(msg, str, len);
-   msg[len] = 0;
-   inst->Data = msg;
-
-   /* comma */
-   if (Parse_String(parseState, ",")) {
-
-      /* The second argument is a register name */
-      if (!Peek_Token(parseState, token))
-         RETURN_ERROR;
-
-      srcReg->RelAddr = GL_FALSE;
-      srcReg->Negate = NEGATE_NONE;
-      srcReg->Swizzle = SWIZZLE_NOOP;
-
-      /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
-       * or an o[n] output register.
-       */
-      if (token[0] == 'R') {
-         srcReg->File = PROGRAM_TEMPORARY;
-         if (!Parse_TempReg(parseState, &idx))
-            RETURN_ERROR;
-	 srcReg->Index = idx;
-      }
-      else if (token[0] == 'c') {
-         srcReg->File = PROGRAM_ENV_PARAM;
-         if (!Parse_ParamReg(parseState, srcReg))
-            RETURN_ERROR;
-      }
-      else if (token[0] == 'v') {
-         srcReg->File = PROGRAM_INPUT;
-         if (!Parse_AttribReg(parseState, &idx))
-            RETURN_ERROR;
-	 srcReg->Index = idx;
-      }
-      else if (token[0] == 'o') {
-         srcReg->File = PROGRAM_OUTPUT;
-         if (!Parse_OutputReg(parseState, &idx))
-            RETURN_ERROR;
-	 srcReg->Index = idx;
-      }
-      else {
-         RETURN_ERROR2("Bad source register name", token);
-      }
-   }
-   else {
-      srcReg->File = PROGRAM_UNDEFINED;
-   }
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OptionSequence(struct parse_state *parseState,
-                     struct prog_instruction program[])
-{
-   (void) program;
-   while (1) {
-      if (!Parse_String(parseState, "OPTION"))
-         return GL_TRUE;  /* ok, not an OPTION statement */
-      if (Parse_String(parseState, "NV_position_invariant")) {
-         parseState->isPositionInvariant = GL_TRUE;
-      }
-      else {
-         RETURN_ERROR1("unexpected OPTION statement");
-      }
-      if (!Parse_String(parseState, ";"))
-         return GL_FALSE;
-   }
-}
-
-
-static GLboolean
-Parse_InstructionSequence(struct parse_state *parseState,
-                          struct prog_instruction program[])
-{
-   while (1) {
-      struct prog_instruction *inst = program + parseState->numInst;
-
-      /* Initialize the instruction */
-      _mesa_init_instructions(inst, 1);
-
-      if (Parse_String(parseState, "MOV")) {
-         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "LIT")) {
-         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "ABS")) {
-         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "MUL")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "ADD")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "DP3")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "DP4")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "DST")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "MIN")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "MAX")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "SLT")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "SGE")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "DPH")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "SUB")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "MAD")) {
-         if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "RCP")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "RSQ")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "EXP")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "LOG")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "RCC")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "ARL")) {
-         if (!Parse_AddressInstruction(parseState, inst))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "PRINT")) {
-         if (!Parse_PrintInstruction(parseState, inst))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "END")) {
-         if (!Parse_EndInstruction(parseState, inst))
-            RETURN_ERROR;
-         else {
-            parseState->numInst++;
-            return GL_TRUE;  /* all done */
-         }
-      }
-      else {
-         /* bad instruction name */
-         RETURN_ERROR1("Unexpected token");
-      }
-
-      /* examine input/output registers */
-      if (inst->DstReg.File == PROGRAM_OUTPUT)
-         parseState->outputsWritten |= (1 << inst->DstReg.Index);
-      else if (inst->DstReg.File == PROGRAM_ENV_PARAM)
-         parseState->anyProgRegsWritten = GL_TRUE;
-
-      if (inst->SrcReg[0].File == PROGRAM_INPUT)
-         parseState->inputsRead |= (1 << inst->SrcReg[0].Index);
-      if (inst->SrcReg[1].File == PROGRAM_INPUT)
-         parseState->inputsRead |= (1 << inst->SrcReg[1].Index);
-      if (inst->SrcReg[2].File == PROGRAM_INPUT)
-         parseState->inputsRead |= (1 << inst->SrcReg[2].Index);
-
-      parseState->numInst++;
-
-      if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS)
-         RETURN_ERROR1("Program too long");
-   }
-
-   RETURN_ERROR;
-}
-
-
-static GLboolean
-Parse_Program(struct parse_state *parseState,
-              struct prog_instruction instBuffer[])
-{
-   if (parseState->isVersion1_1) {
-      if (!Parse_OptionSequence(parseState, instBuffer)) {
-         return GL_FALSE;
-      }
-   }
-   return Parse_InstructionSequence(parseState, instBuffer);
-}
-
-
-/**
- * Parse/compile the 'str' returning the compiled 'program'.
- * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
- * indicates the position of the error in 'str'.
- */
-void
-_mesa_parse_nv_vertex_program(struct gl_context *ctx, GLenum dstTarget,
-                              const GLubyte *str, GLsizei len,
-                              struct gl_vertex_program *program)
-{
-   struct parse_state parseState;
-   struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
-   struct prog_instruction *newInst;
-   GLenum target;
-   GLubyte *programString;
-
-   /* Make a null-terminated copy of the program string */
-   programString = (GLubyte *) MALLOC(len + 1);
-   if (!programString) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-      return;
-   }
-   memcpy(programString, str, len);
-   programString[len] = 0;
-
-   /* Get ready to parse */
-   parseState.ctx = ctx;
-   parseState.start = programString;
-   parseState.isPositionInvariant = GL_FALSE;
-   parseState.isVersion1_1 = GL_FALSE;
-   parseState.numInst = 0;
-   parseState.inputsRead = 0;
-   parseState.outputsWritten = 0;
-   parseState.anyProgRegsWritten = GL_FALSE;
-   parseState.indirectRegisterFiles = 0x0;
-
-   /* Reset error state */
-   _mesa_set_program_error(ctx, -1, NULL);
-
-   /* check the program header */
-   if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) {
-      target = GL_VERTEX_PROGRAM_NV;
-      parseState.pos = programString + 7;
-      parseState.isStateProgram = GL_FALSE;
-   }
-   else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) {
-      target = GL_VERTEX_PROGRAM_NV;
-      parseState.pos = programString + 7;
-      parseState.isStateProgram = GL_FALSE;
-      parseState.isVersion1_1 = GL_TRUE;
-   }
-   else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) {
-      target = GL_VERTEX_STATE_PROGRAM_NV;
-      parseState.pos = programString + 8;
-      parseState.isStateProgram = GL_TRUE;
-   }
-   else {
-      /* invalid header */
-      ctx->Program.ErrorPos = 0;
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
-      return;
-   }
-
-   /* make sure target and header match */
-   if (target != dstTarget) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glLoadProgramNV(target mismatch)");
-      return;
-   }
-
-
-   if (Parse_Program(&parseState, instBuffer)) {
-      gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
-      int i;
-
-      /* successful parse! */
-
-      if (parseState.isStateProgram) {
-         if (!parseState.anyProgRegsWritten) {
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glLoadProgramNV(c[#] not written)");
-            return;
-         }
-      }
-      else {
-         if (!parseState.isPositionInvariant &&
-             !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) {
-            /* bit 1 = HPOS register */
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glLoadProgramNV(HPOS not written)");
-            return;
-         }
-      }
-
-      /* copy the compiled instructions */
-      assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS);
-      newInst = _mesa_alloc_instructions(parseState.numInst);
-      if (!newInst) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-         free(programString);
-         return;  /* out of memory */
-      }
-      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
-
-      /* install the program */
-      program->Base.Target = target;
-      if (program->Base.String) {
-         free(program->Base.String);
-      }
-      program->Base.String = programString;
-      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
-      if (program->Base.Instructions) {
-         free(program->Base.Instructions);
-      }
-      program->Base.Instructions = newInst;
-      program->Base.InputsRead = parseState.inputsRead;
-      if (parseState.isPositionInvariant)
-         program->Base.InputsRead |= VERT_BIT_POS;
-      program->Base.NumInstructions = parseState.numInst;
-      program->Base.OutputsWritten = parseState.outputsWritten;
-      program->IsPositionInvariant = parseState.isPositionInvariant;
-      program->IsNVProgram = GL_TRUE;
-
-#ifdef DEBUG_foo
-      printf("--- glLoadProgramNV result ---\n");
-      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
-      printf("------------------------------\n");
-#endif
-
-      if (program->Base.Parameters)
-	 _mesa_free_parameter_list(program->Base.Parameters);
-
-      program->Base.Parameters = _mesa_new_parameter_list ();
-      program->Base.NumParameters = 0;
-
-      program->Base.IndirectRegisterFiles = parseState.indirectRegisterFiles;
-
-      state_tokens[0] = STATE_VERTEX_PROGRAM;
-      state_tokens[1] = STATE_ENV;
-      /* Add refs to all of the potential params, in order.  If we want to not
-       * upload everything, _mesa_layout_parameters is the answer.
-       */
-      for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
-	 GLint index;
-	 state_tokens[2] = i;
-	 index = _mesa_add_state_reference(program->Base.Parameters,
-					   state_tokens);
-	 assert(index == i);
-      }
-      program->Base.NumParameters = program->Base.Parameters->NumParameters;
-
-      _mesa_setup_nv_temporary_count(ctx, &program->Base);
-      _mesa_emit_nv_temp_initialization(ctx, &program->Base);
-   }
-   else {
-      /* Error! */
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
-      /* NOTE: _mesa_set_program_error would have been called already */
-      /* GL_NV_vertex_program isn't supposed to set the error string
-       * so we reset it here.
-       */
-      _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL);
-   }
-}
-
-
-const char *
-_mesa_nv_vertex_input_register_name(GLuint i)
-{
-   ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS);
-   return InputRegisters[i];
-}
-
-
-const char *
-_mesa_nv_vertex_output_register_name(GLuint i)
-{
-   ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
-   return OutputRegisters[i];
-}
-
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.2
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file nvvertparse.c
+ * NVIDIA vertex program parser.
+ * \author Brian Paul
+ */
+
+/*
+ * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1:
+ *
+ * Portions of this software may use or implement intellectual
+ * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
+ * any and all warranties with respect to such intellectual property,
+ * including any use thereof or modifications thereto.
+ */
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "main/nvprogram.h"
+#include "nvvertparse.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "program.h"
+
+
+/**
+ * Current parsing state.  This structure is passed among the parsing
+ * functions and keeps track of the current parser position and various
+ * program attributes.
+ */
+struct parse_state {
+   struct gl_context *ctx;
+   const GLubyte *start;
+   const GLubyte *pos;
+   const GLubyte *curLine;
+   GLboolean isStateProgram;
+   GLboolean isPositionInvariant;
+   GLboolean isVersion1_1;
+   GLbitfield inputsRead;
+   GLbitfield outputsWritten;
+   GLboolean anyProgRegsWritten;
+   GLboolean indirectRegisterFiles;
+   GLuint numInst;                 /* number of instructions parsed */
+};
+
+
+/*
+ * Called whenever we find an error during parsing.
+ */
+static void
+record_error(struct parse_state *parseState, const char *msg, int lineNo)
+{
+#ifdef DEBUG
+   GLint line, column;
+   const GLubyte *lineStr;
+   lineStr = _mesa_find_line_column(parseState->start,
+                                    parseState->pos, &line, &column);
+   _mesa_debug(parseState->ctx,
+               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
+               lineNo, line, column, (char *) lineStr, msg);
+   free((void *) lineStr);
+#else
+   (void) lineNo;
+#endif
+
+   /* Check that no error was already recorded.  Only record the first one. */
+   if (parseState->ctx->Program.ErrorString[0] == 0) {
+      _mesa_set_program_error(parseState->ctx,
+                              parseState->pos - parseState->start,
+                              msg);
+   }
+}
+
+
+#define RETURN_ERROR							\
+do {									\
+   record_error(parseState, "Unexpected end of input.", __LINE__);	\
+   return GL_FALSE;							\
+} while(0)
+
+#define RETURN_ERROR1(msg)						\
+do {									\
+   record_error(parseState, msg, __LINE__);				\
+   return GL_FALSE;							\
+} while(0)
+
+#define RETURN_ERROR2(msg1, msg2)					\
+do {									\
+   char err[1000];							\
+   sprintf(err, "%s %s", msg1, msg2);				\
+   record_error(parseState, err, __LINE__);				\
+   return GL_FALSE;							\
+} while(0)
+
+
+
+
+
+static GLboolean IsLetter(GLubyte b)
+{
+   return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z');
+}
+
+
+static GLboolean IsDigit(GLubyte b)
+{
+   return b >= '0' && b <= '9';
+}
+
+
+static GLboolean IsWhitespace(GLubyte b)
+{
+   return b == ' ' || b == '\t' || b == '\n' || b == '\r';
+}
+
+
+/**
+ * Starting at 'str' find the next token.  A token can be an integer,
+ * an identifier or punctuation symbol.
+ * \return <= 0 we found an error, else, return number of characters parsed.
+ */
+static GLint
+GetToken(struct parse_state *parseState, GLubyte *token)
+{
+   const GLubyte *str = parseState->pos;
+   GLint i = 0, j = 0;
+
+   token[0] = 0;
+
+   /* skip whitespace and comments */
+   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
+      if (str[i] == '#') {
+         /* skip comment */
+         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
+            i++;
+         }
+         if (str[i] == '\n' || str[i] == '\r')
+            parseState->curLine = str + i + 1;
+      }
+      else {
+         /* skip whitespace */
+         if (str[i] == '\n' || str[i] == '\r')
+            parseState->curLine = str + i + 1;
+         i++;
+      }
+   }
+
+   if (str[i] == 0)
+      return -i;
+
+   /* try matching an integer */
+   while (str[i] && IsDigit(str[i])) {
+      token[j++] = str[i++];
+   }
+   if (j > 0 || !str[i]) {
+      token[j] = 0;
+      return i;
+   }
+
+   /* try matching an identifier */
+   if (IsLetter(str[i])) {
+      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
+         token[j++] = str[i++];
+      }
+      token[j] = 0;
+      return i;
+   }
+
+   /* punctuation character */
+   if (str[i]) {
+      token[0] = str[i++];
+      token[1] = 0;
+      return i;
+   }
+
+   /* end of input */
+   token[0] = 0;
+   return i;
+}
+
+
+/**
+ * Get next token from input stream and increment stream pointer past token.
+ */
+static GLboolean
+Parse_Token(struct parse_state *parseState, GLubyte *token)
+{
+   GLint i;
+   i = GetToken(parseState, token);
+   if (i <= 0) {
+      parseState->pos += (-i);
+      return GL_FALSE;
+   }
+   parseState->pos += i;
+   return GL_TRUE;
+}
+
+
+/**
+ * Get next token from input stream but don't increment stream pointer.
+ */
+static GLboolean
+Peek_Token(struct parse_state *parseState, GLubyte *token)
+{
+   GLint i, len;
+   i = GetToken(parseState, token);
+   if (i <= 0) {
+      parseState->pos += (-i);
+      return GL_FALSE;
+   }
+   len = (GLint) strlen((const char *) token);
+   parseState->pos += (i - len);
+   return GL_TRUE;
+}
+
+
+/**
+ * Try to match 'pattern' as the next token after any whitespace/comments.
+ * Advance the current parsing position only if we match the pattern.
+ * \return GL_TRUE if pattern is matched, GL_FALSE otherwise.
+ */
+static GLboolean
+Parse_String(struct parse_state *parseState, const char *pattern)
+{
+   const GLubyte *m;
+   GLint i;
+
+   /* skip whitespace and comments */
+   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
+      if (*parseState->pos == '#') {
+         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
+            parseState->pos += 1;
+         }
+         if (*parseState->pos == '\n' || *parseState->pos == '\r')
+            parseState->curLine = parseState->pos + 1;
+      }
+      else {
+         /* skip whitespace */
+         if (*parseState->pos == '\n' || *parseState->pos == '\r')
+            parseState->curLine = parseState->pos + 1;
+         parseState->pos += 1;
+      }
+   }
+
+   /* Try to match the pattern */
+   m = parseState->pos;
+   for (i = 0; pattern[i]; i++) {
+      if (*m != (GLubyte) pattern[i])
+         return GL_FALSE;
+      m += 1;
+   }
+   parseState->pos = m;
+
+   return GL_TRUE; /* success */
+}
+
+
+/**********************************************************************/
+
+static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = {
+   "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7",
+   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
+};
+
+static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
+   "HPOS", "COL0", "COL1", "FOGC", 
+   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", 
+   "PSIZ", "BFC0", "BFC1", NULL
+};
+
+
+
+/**
+ * Parse a temporary register: Rnn
+ */
+static GLboolean
+Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
+{
+   GLubyte token[100];
+
+   /* Should be 'R##' */
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+   if (token[0] != 'R')
+      RETURN_ERROR1("Expected R##");
+
+   if (IsDigit(token[1])) {
+      GLint reg = atoi((char *) (token + 1));
+      if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS)
+         RETURN_ERROR1("Bad temporary register name");
+      *tempRegNum = reg;
+   }
+   else {
+      RETURN_ERROR1("Bad temporary register name");
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse address register "A0.x"
+ */
+static GLboolean
+Parse_AddrReg(struct parse_state *parseState)
+{
+   /* match 'A0' */
+   if (!Parse_String(parseState, "A0"))
+      RETURN_ERROR;
+
+   /* match '.' */
+   if (!Parse_String(parseState, "."))
+      RETURN_ERROR;
+
+   /* match 'x' */
+   if (!Parse_String(parseState, "x"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse absolute program parameter register "c[##]"
+ */
+static GLboolean
+Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum)
+{
+   GLubyte token[100];
+
+   if (!Parse_String(parseState, "c"))
+      RETURN_ERROR;
+
+   if (!Parse_String(parseState, "["))
+      RETURN_ERROR;
+
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (IsDigit(token[0])) {
+      /* a numbered program parameter register */
+      GLint reg = atoi((char *) token);
+      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
+         RETURN_ERROR1("Bad program parameter number");
+      *regNum = reg;
+   }
+   else {
+      RETURN_ERROR;
+   }
+
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg)
+{
+   GLubyte token[100];
+
+   if (!Parse_String(parseState, "c"))
+      RETURN_ERROR;
+
+   if (!Parse_String(parseState, "["))
+      RETURN_ERROR;
+
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (IsDigit(token[0])) {
+      /* a numbered program parameter register */
+      GLint reg;
+      (void) Parse_Token(parseState, token);
+      reg = atoi((char *) token);
+      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
+         RETURN_ERROR1("Bad program parameter number");
+      srcReg->File = PROGRAM_ENV_PARAM;
+      srcReg->Index = reg;
+   }
+   else if (strcmp((const char *) token, "A0") == 0) {
+      /* address register "A0.x" */
+      if (!Parse_AddrReg(parseState))
+         RETURN_ERROR;
+
+      srcReg->RelAddr = GL_TRUE;
+      srcReg->File = PROGRAM_ENV_PARAM;
+      parseState->indirectRegisterFiles |= (1 << srcReg->File);
+      /* Look for +/-N offset */
+      if (!Peek_Token(parseState, token))
+         RETURN_ERROR;
+
+      if (token[0] == '-' || token[0] == '+') {
+         const GLubyte sign = token[0];
+         (void) Parse_Token(parseState, token); /* consume +/- */
+
+         /* an integer should be next */
+         if (!Parse_Token(parseState, token))
+            RETURN_ERROR;
+
+         if (IsDigit(token[0])) {
+            const GLint k = atoi((char *) token);
+            if (sign == '-') {
+               if (k > 64)
+                  RETURN_ERROR1("Bad address offset");
+               srcReg->Index = -k;
+            }
+            else {
+               if (k > 63)
+                  RETURN_ERROR1("Bad address offset");
+               srcReg->Index = k;
+            }
+         }
+         else {
+            RETURN_ERROR;
+         }
+      }
+      else {
+         /* probably got a ']', catch it below */
+      }
+   }
+   else {
+      RETURN_ERROR;
+   }
+
+   /* Match closing ']' */
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse v[#] or v[<name>]
+ */
+static GLboolean
+Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum)
+{
+   GLubyte token[100];
+   GLint j;
+
+   /* Match 'v' */
+   if (!Parse_String(parseState, "v"))
+      RETURN_ERROR;
+
+   /* Match '[' */
+   if (!Parse_String(parseState, "["))
+      RETURN_ERROR;
+
+   /* match number or named register */
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (parseState->isStateProgram && token[0] != '0')
+      RETURN_ERROR1("Only v[0] accessible in vertex state programs");
+
+   if (IsDigit(token[0])) {
+      GLint reg = atoi((char *) token);
+      if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS)
+         RETURN_ERROR1("Bad vertex attribute register name");
+      *tempRegNum = reg;
+   }
+   else {
+      for (j = 0; InputRegisters[j]; j++) {
+         if (strcmp((const char *) token, InputRegisters[j]) == 0) {
+            *tempRegNum = j;
+            break;
+         }
+      }
+      if (!InputRegisters[j]) {
+         /* unknown input register label */
+         RETURN_ERROR2("Bad register name", token);
+      }
+   }
+
+   /* Match '[' */
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
+{
+   GLubyte token[100];
+   GLint start, j;
+
+   /* Match 'o' */
+   if (!Parse_String(parseState, "o"))
+      RETURN_ERROR;
+
+   /* Match '[' */
+   if (!Parse_String(parseState, "["))
+      RETURN_ERROR;
+
+   /* Get output reg name */
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (parseState->isPositionInvariant)
+      start = 1; /* skip HPOS register name */
+   else
+      start = 0;
+
+   /* try to match an output register name */
+   for (j = start; OutputRegisters[j]; j++) {
+      if (strcmp((const char *) token, OutputRegisters[j]) == 0) {
+         *outputRegNum = j;
+         break;
+      }
+   }
+   if (!OutputRegisters[j])
+      RETURN_ERROR1("Unrecognized output register name");
+
+   /* Match ']' */
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR1("Expected ]");
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg)
+{
+   GLubyte token[100];
+   GLint idx;
+
+   /* Dst reg can be R<n> or o[n] */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (token[0] == 'R') {
+      /* a temporary register */
+      dstReg->File = PROGRAM_TEMPORARY;
+      if (!Parse_TempReg(parseState, &idx))
+         RETURN_ERROR;
+      dstReg->Index = idx;
+   }
+   else if (!parseState->isStateProgram && token[0] == 'o') {
+      /* an output register */
+      dstReg->File = PROGRAM_OUTPUT;
+      if (!Parse_OutputReg(parseState, &idx))
+         RETURN_ERROR;
+      dstReg->Index = idx;
+   }
+   else if (parseState->isStateProgram && token[0] == 'c' &&
+            parseState->isStateProgram) {
+      /* absolute program parameter register */
+      /* Only valid for vertex state programs */
+      dstReg->File = PROGRAM_ENV_PARAM;
+      if (!Parse_AbsParamReg(parseState, &idx))
+         RETURN_ERROR;
+      dstReg->Index = idx;
+   }
+   else {
+      RETURN_ERROR1("Bad destination register name");
+   }
+
+   /* Parse optional write mask */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (token[0] == '.') {
+      /* got a mask */
+      GLint k = 0;
+
+      if (!Parse_String(parseState, "."))
+         RETURN_ERROR;
+
+      if (!Parse_Token(parseState, token))
+         RETURN_ERROR;
+
+      dstReg->WriteMask = 0;
+
+      if (token[k] == 'x') {
+         dstReg->WriteMask |= WRITEMASK_X;
+         k++;
+      }
+      if (token[k] == 'y') {
+         dstReg->WriteMask |= WRITEMASK_Y;
+         k++;
+      }
+      if (token[k] == 'z') {
+         dstReg->WriteMask |= WRITEMASK_Z;
+         k++;
+      }
+      if (token[k] == 'w') {
+         dstReg->WriteMask |= WRITEMASK_W;
+         k++;
+      }
+      if (k == 0) {
+         RETURN_ERROR1("Bad writemask character");
+      }
+      return GL_TRUE;
+   }
+   else {
+      dstReg->WriteMask = WRITEMASK_XYZW;
+      return GL_TRUE;
+   }
+}
+
+
+static GLboolean
+Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
+{
+   GLubyte token[100];
+   GLint idx;
+
+   srcReg->RelAddr = GL_FALSE;
+
+   /* check for '-' */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+   if (token[0] == '-') {
+      (void) Parse_String(parseState, "-");
+      srcReg->Negate = NEGATE_XYZW;
+      if (!Peek_Token(parseState, token))
+         RETURN_ERROR;
+   }
+   else {
+      srcReg->Negate = NEGATE_NONE;
+   }
+
+   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
+   if (token[0] == 'R') {
+      srcReg->File = PROGRAM_TEMPORARY;
+      if (!Parse_TempReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else if (token[0] == 'c') {
+      if (!Parse_ParamReg(parseState, srcReg))
+         RETURN_ERROR;
+   }
+   else if (token[0] == 'v') {
+      srcReg->File = PROGRAM_INPUT;
+      if (!Parse_AttribReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else {
+      RETURN_ERROR2("Bad source register name", token);
+   }
+
+   /* init swizzle fields */
+   srcReg->Swizzle = SWIZZLE_NOOP;
+
+   /* Look for optional swizzle suffix */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+   if (token[0] == '.') {
+      (void) Parse_String(parseState, ".");  /* consume . */
+
+      if (!Parse_Token(parseState, token))
+         RETURN_ERROR;
+
+      if (token[1] == 0) {
+         /* single letter swizzle */
+         if (token[0] == 'x')
+            srcReg->Swizzle = SWIZZLE_XXXX;
+         else if (token[0] == 'y')
+            srcReg->Swizzle = SWIZZLE_YYYY;
+         else if (token[0] == 'z')
+            srcReg->Swizzle = SWIZZLE_ZZZZ;
+         else if (token[0] == 'w')
+            srcReg->Swizzle = SWIZZLE_WWWW;
+         else
+            RETURN_ERROR1("Expected x, y, z, or w");
+      }
+      else {
+         /* 2, 3 or 4-component swizzle */
+         GLint k;
+
+         srcReg->Swizzle = 0;
+
+         for (k = 0; token[k] && k < 5; k++) {
+            if (token[k] == 'x')
+               srcReg->Swizzle |= 0 << (k*3);
+            else if (token[k] == 'y')
+               srcReg->Swizzle |= 1 << (k*3);
+            else if (token[k] == 'z')
+               srcReg->Swizzle |= 2 << (k*3);
+            else if (token[k] == 'w')
+               srcReg->Swizzle |= 3 << (k*3);
+            else
+               RETURN_ERROR;
+         }
+         if (k >= 5)
+            RETURN_ERROR;
+      }
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
+{
+   GLubyte token[100];
+   GLint idx;
+
+   srcReg->RelAddr = GL_FALSE;
+
+   /* check for '-' */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+   if (token[0] == '-') {
+      srcReg->Negate = NEGATE_XYZW;
+      (void) Parse_String(parseState, "-"); /* consume '-' */
+      if (!Peek_Token(parseState, token))
+         RETURN_ERROR;
+   }
+   else {
+      srcReg->Negate = NEGATE_NONE;
+   }
+
+   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
+   if (token[0] == 'R') {
+      srcReg->File = PROGRAM_TEMPORARY;
+      if (!Parse_TempReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else if (token[0] == 'c') {
+      if (!Parse_ParamReg(parseState, srcReg))
+         RETURN_ERROR;
+   }
+   else if (token[0] == 'v') {
+      srcReg->File = PROGRAM_INPUT;
+      if (!Parse_AttribReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else {
+      RETURN_ERROR2("Bad source register name", token);
+   }
+
+   /* Look for .[xyzw] suffix */
+   if (!Parse_String(parseState, "."))
+      RETURN_ERROR;
+
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (token[0] == 'x' && token[1] == 0) {
+      srcReg->Swizzle = 0;
+   }
+   else if (token[0] == 'y' && token[1] == 0) {
+      srcReg->Swizzle = 1;
+   }
+   else if (token[0] == 'z' && token[1] == 0) {
+      srcReg->Swizzle = 2;
+   }
+   else if (token[0] == 'w' && token[1] == 0) {
+      srcReg->Swizzle = 3;
+   }
+   else {
+      RETURN_ERROR1("Bad scalar source suffix");
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLint
+Parse_UnaryOpInstruction(struct parse_state *parseState,
+                         struct prog_instruction *inst,
+                         enum prog_opcode opcode)
+{
+   if (opcode == OPCODE_ABS && !parseState->isVersion1_1)
+      RETURN_ERROR1("ABS illegal for vertex program 1.0");
+
+   inst->Opcode = opcode;
+
+   /* dest reg */
+   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_BiOpInstruction(struct parse_state *parseState,
+                      struct prog_instruction *inst,
+                      enum prog_opcode opcode)
+{
+   if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
+      RETURN_ERROR1("DPH illegal for vertex program 1.0");
+   if (opcode == OPCODE_SUB && !parseState->isVersion1_1)
+      RETURN_ERROR1("SUB illegal for vertex program 1.0");
+
+   inst->Opcode = opcode;
+
+   /* dest reg */
+   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* first src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* second src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   /* make sure we don't reference more than one program parameter register */
+   if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
+       inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
+       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
+      RETURN_ERROR1("Can't reference two program parameter registers");
+
+   /* make sure we don't reference more than one vertex attribute register */
+   if (inst->SrcReg[0].File == PROGRAM_INPUT &&
+       inst->SrcReg[1].File == PROGRAM_INPUT &&
+       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
+      RETURN_ERROR1("Can't reference two vertex attribute registers");
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_TriOpInstruction(struct parse_state *parseState,
+                       struct prog_instruction *inst,
+                       enum prog_opcode opcode)
+{
+   inst->Opcode = opcode;
+
+   /* dest reg */
+   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* first src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* second src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* third src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   /* make sure we don't reference more than one program parameter register */
+   if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
+       (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
+       (inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
+      RETURN_ERROR1("Can only reference one program register");
+
+   /* make sure we don't reference more than one vertex attribute register */
+   if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
+        inst->SrcReg[1].File == PROGRAM_INPUT &&
+        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
+       (inst->SrcReg[0].File == PROGRAM_INPUT &&
+        inst->SrcReg[2].File == PROGRAM_INPUT &&
+        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
+       (inst->SrcReg[1].File == PROGRAM_INPUT &&
+        inst->SrcReg[2].File == PROGRAM_INPUT &&
+        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
+      RETURN_ERROR1("Can only reference one input register");
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ScalarInstruction(struct parse_state *parseState,
+                        struct prog_instruction *inst,
+                        enum prog_opcode opcode)
+{
+   if (opcode == OPCODE_RCC && !parseState->isVersion1_1)
+      RETURN_ERROR1("RCC illegal for vertex program 1.0");
+
+   inst->Opcode = opcode;
+
+   /* dest reg */
+   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* first src arg */
+   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+   inst->Opcode = OPCODE_ARL;
+
+   /* Make ARB_vp backends happy */
+   inst->DstReg.File = PROGRAM_ADDRESS;
+   inst->DstReg.WriteMask = WRITEMASK_X;
+   inst->DstReg.Index = 0;
+
+   /* dest A0 reg */
+   if (!Parse_AddrReg(parseState))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* parse src reg */
+   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+   GLubyte token[100];
+
+   inst->Opcode = OPCODE_END;
+
+   /* this should fail! */
+   if (Parse_Token(parseState, token))
+      RETURN_ERROR2("Unexpected token after END:", token);
+   else
+      return GL_TRUE;
+}
+
+
+/**
+ * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
+ * the vertex program developer.
+ * The NV_vertex_program extension grammar is modified as follows:
+ *
+ *  <instruction>        ::= <ARL-instruction>
+ *                         | ...
+ *                         | <PRINT-instruction>
+ *
+ *  <PRINT-instruction>  ::= "PRINT" <string literal>
+ *                         | "PRINT" <string literal> "," <srcReg>
+ *                         | "PRINT" <string literal> "," <dstReg>
+ */
+static GLboolean
+Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+   const GLubyte *str;
+   GLubyte *msg;
+   GLuint len;
+   GLubyte token[100];
+   struct prog_src_register *srcReg = &inst->SrcReg[0];
+   GLint idx;
+
+   inst->Opcode = OPCODE_PRINT;
+
+   /* The first argument is a literal string 'just like this' */
+   if (!Parse_String(parseState, "'"))
+      RETURN_ERROR;
+
+   str = parseState->pos;
+   for (len = 0; str[len] != '\''; len++) /* find closing quote */
+      ;
+   parseState->pos += len + 1;
+   msg = (GLubyte*) malloc(len + 1);
+
+   memcpy(msg, str, len);
+   msg[len] = 0;
+   inst->Data = msg;
+
+   /* comma */
+   if (Parse_String(parseState, ",")) {
+
+      /* The second argument is a register name */
+      if (!Peek_Token(parseState, token))
+         RETURN_ERROR;
+
+      srcReg->RelAddr = GL_FALSE;
+      srcReg->Negate = NEGATE_NONE;
+      srcReg->Swizzle = SWIZZLE_NOOP;
+
+      /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
+       * or an o[n] output register.
+       */
+      if (token[0] == 'R') {
+         srcReg->File = PROGRAM_TEMPORARY;
+         if (!Parse_TempReg(parseState, &idx))
+            RETURN_ERROR;
+	 srcReg->Index = idx;
+      }
+      else if (token[0] == 'c') {
+         srcReg->File = PROGRAM_ENV_PARAM;
+         if (!Parse_ParamReg(parseState, srcReg))
+            RETURN_ERROR;
+      }
+      else if (token[0] == 'v') {
+         srcReg->File = PROGRAM_INPUT;
+         if (!Parse_AttribReg(parseState, &idx))
+            RETURN_ERROR;
+	 srcReg->Index = idx;
+      }
+      else if (token[0] == 'o') {
+         srcReg->File = PROGRAM_OUTPUT;
+         if (!Parse_OutputReg(parseState, &idx))
+            RETURN_ERROR;
+	 srcReg->Index = idx;
+      }
+      else {
+         RETURN_ERROR2("Bad source register name", token);
+      }
+   }
+   else {
+      srcReg->File = PROGRAM_UNDEFINED;
+   }
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_OptionSequence(struct parse_state *parseState,
+                     struct prog_instruction program[])
+{
+   (void) program;
+   while (1) {
+      if (!Parse_String(parseState, "OPTION"))
+         return GL_TRUE;  /* ok, not an OPTION statement */
+      if (Parse_String(parseState, "NV_position_invariant")) {
+         parseState->isPositionInvariant = GL_TRUE;
+      }
+      else {
+         RETURN_ERROR1("unexpected OPTION statement");
+      }
+      if (!Parse_String(parseState, ";"))
+         return GL_FALSE;
+   }
+}
+
+
+static GLboolean
+Parse_InstructionSequence(struct parse_state *parseState,
+                          struct prog_instruction program[])
+{
+   while (1) {
+      struct prog_instruction *inst = program + parseState->numInst;
+
+      /* Initialize the instruction */
+      _mesa_init_instructions(inst, 1);
+
+      if (Parse_String(parseState, "MOV")) {
+         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "LIT")) {
+         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "ABS")) {
+         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "MUL")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "ADD")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "DP3")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "DP4")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "DST")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "MIN")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "MAX")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "SLT")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "SGE")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "DPH")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "SUB")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "MAD")) {
+         if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "RCP")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "RSQ")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "EXP")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "LOG")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "RCC")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "ARL")) {
+         if (!Parse_AddressInstruction(parseState, inst))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "PRINT")) {
+         if (!Parse_PrintInstruction(parseState, inst))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "END")) {
+         if (!Parse_EndInstruction(parseState, inst))
+            RETURN_ERROR;
+         else {
+            parseState->numInst++;
+            return GL_TRUE;  /* all done */
+         }
+      }
+      else {
+         /* bad instruction name */
+         RETURN_ERROR1("Unexpected token");
+      }
+
+      /* examine input/output registers */
+      if (inst->DstReg.File == PROGRAM_OUTPUT)
+         parseState->outputsWritten |= (1 << inst->DstReg.Index);
+      else if (inst->DstReg.File == PROGRAM_ENV_PARAM)
+         parseState->anyProgRegsWritten = GL_TRUE;
+
+      if (inst->SrcReg[0].File == PROGRAM_INPUT)
+         parseState->inputsRead |= (1 << inst->SrcReg[0].Index);
+      if (inst->SrcReg[1].File == PROGRAM_INPUT)
+         parseState->inputsRead |= (1 << inst->SrcReg[1].Index);
+      if (inst->SrcReg[2].File == PROGRAM_INPUT)
+         parseState->inputsRead |= (1 << inst->SrcReg[2].Index);
+
+      parseState->numInst++;
+
+      if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS)
+         RETURN_ERROR1("Program too long");
+   }
+
+   RETURN_ERROR;
+}
+
+
+static GLboolean
+Parse_Program(struct parse_state *parseState,
+              struct prog_instruction instBuffer[])
+{
+   if (parseState->isVersion1_1) {
+      if (!Parse_OptionSequence(parseState, instBuffer)) {
+         return GL_FALSE;
+      }
+   }
+   return Parse_InstructionSequence(parseState, instBuffer);
+}
+
+
+/**
+ * Parse/compile the 'str' returning the compiled 'program'.
+ * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
+ * indicates the position of the error in 'str'.
+ */
+void
+_mesa_parse_nv_vertex_program(struct gl_context *ctx, GLenum dstTarget,
+                              const GLubyte *str, GLsizei len,
+                              struct gl_vertex_program *program)
+{
+   struct parse_state parseState;
+   struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
+   struct prog_instruction *newInst;
+   GLenum target;
+   GLubyte *programString;
+
+   /* Make a null-terminated copy of the program string */
+   programString = (GLubyte *) MALLOC(len + 1);
+   if (!programString) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+      return;
+   }
+   memcpy(programString, str, len);
+   programString[len] = 0;
+
+   /* Get ready to parse */
+   parseState.ctx = ctx;
+   parseState.start = programString;
+   parseState.isPositionInvariant = GL_FALSE;
+   parseState.isVersion1_1 = GL_FALSE;
+   parseState.numInst = 0;
+   parseState.inputsRead = 0;
+   parseState.outputsWritten = 0;
+   parseState.anyProgRegsWritten = GL_FALSE;
+   parseState.indirectRegisterFiles = 0x0;
+
+   /* Reset error state */
+   _mesa_set_program_error(ctx, -1, NULL);
+
+   /* check the program header */
+   if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) {
+      target = GL_VERTEX_PROGRAM_NV;
+      parseState.pos = programString + 7;
+      parseState.isStateProgram = GL_FALSE;
+   }
+   else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) {
+      target = GL_VERTEX_PROGRAM_NV;
+      parseState.pos = programString + 7;
+      parseState.isStateProgram = GL_FALSE;
+      parseState.isVersion1_1 = GL_TRUE;
+   }
+   else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) {
+      target = GL_VERTEX_STATE_PROGRAM_NV;
+      parseState.pos = programString + 8;
+      parseState.isStateProgram = GL_TRUE;
+   }
+   else {
+      /* invalid header */
+      ctx->Program.ErrorPos = 0;
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
+      return;
+   }
+
+   /* make sure target and header match */
+   if (target != dstTarget) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glLoadProgramNV(target mismatch)");
+      return;
+   }
+
+
+   if (Parse_Program(&parseState, instBuffer)) {
+      gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
+      int i;
+
+      /* successful parse! */
+
+      if (parseState.isStateProgram) {
+         if (!parseState.anyProgRegsWritten) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glLoadProgramNV(c[#] not written)");
+            return;
+         }
+      }
+      else {
+         if (!parseState.isPositionInvariant &&
+             !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) {
+            /* bit 1 = HPOS register */
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glLoadProgramNV(HPOS not written)");
+            return;
+         }
+      }
+
+      /* copy the compiled instructions */
+      assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS);
+      newInst = _mesa_alloc_instructions(parseState.numInst);
+      if (!newInst) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+         free(programString);
+         return;  /* out of memory */
+      }
+      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
+
+      /* install the program */
+      program->Base.Target = target;
+      if (program->Base.String) {
+         free(program->Base.String);
+      }
+      program->Base.String = programString;
+      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
+      if (program->Base.Instructions) {
+         free(program->Base.Instructions);
+      }
+      program->Base.Instructions = newInst;
+      program->Base.InputsRead = parseState.inputsRead;
+      if (parseState.isPositionInvariant)
+         program->Base.InputsRead |= VERT_BIT_POS;
+      program->Base.NumInstructions = parseState.numInst;
+      program->Base.OutputsWritten = parseState.outputsWritten;
+      program->IsPositionInvariant = parseState.isPositionInvariant;
+      program->IsNVProgram = GL_TRUE;
+
+#ifdef DEBUG_foo
+      printf("--- glLoadProgramNV result ---\n");
+      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
+      printf("------------------------------\n");
+#endif
+
+      if (program->Base.Parameters)
+	 _mesa_free_parameter_list(program->Base.Parameters);
+
+      program->Base.Parameters = _mesa_new_parameter_list ();
+      program->Base.NumParameters = 0;
+
+      program->Base.IndirectRegisterFiles = parseState.indirectRegisterFiles;
+
+      state_tokens[0] = STATE_VERTEX_PROGRAM;
+      state_tokens[1] = STATE_ENV;
+      /* Add refs to all of the potential params, in order.  If we want to not
+       * upload everything, _mesa_layout_parameters is the answer.
+       */
+      for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
+	 GLint index;
+	 state_tokens[2] = i;
+	 index = _mesa_add_state_reference(program->Base.Parameters,
+					   state_tokens);
+	 assert(index == i);
+      }
+      program->Base.NumParameters = program->Base.Parameters->NumParameters;
+
+      _mesa_setup_nv_temporary_count(&program->Base);
+      _mesa_emit_nv_temp_initialization(ctx, &program->Base);
+   }
+   else {
+      /* Error! */
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
+      /* NOTE: _mesa_set_program_error would have been called already */
+      /* GL_NV_vertex_program isn't supposed to set the error string
+       * so we reset it here.
+       */
+      _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL);
+   }
+}
+
+
+const char *
+_mesa_nv_vertex_input_register_name(GLuint i)
+{
+   ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS);
+   return InputRegisters[i];
+}
+
+
+const char *
+_mesa_nv_vertex_output_register_name(GLuint i)
+{
+   ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
+   return OutputRegisters[i];
+}
+
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index a41e9e872..0ad9e1286 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -85,6 +85,9 @@ void st_init_limits(struct st_context *st)
    c->MaxTextureRectSize
       = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE);
 
+   c->MaxArrayTextureLayers
+      = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);
+
    c->MaxTextureImageUnits
       = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS),
             MAX_TEXTURE_IMAGE_UNITS);
@@ -170,6 +173,12 @@ void st_init_limits(struct st_context *st)
       /* raise MaxParameters if native support is higher */
       pc->MaxParameters            = MAX2(pc->MaxParameters, pc->MaxNativeParameters);
 
+      /* Gallium doesn't really care about local vs. env parameters so use the
+       * same limits.
+       */
+      pc->MaxLocalParams = pc->MaxParameters;
+      pc->MaxEnvParams = pc->MaxParameters;
+
       options->EmitNoNoise = TRUE;
 
       /* TODO: make these more fine-grained if anyone needs it */
@@ -499,7 +508,7 @@ void st_init_extensions(struct st_context *st)
    }
 
    /* GL_EXT_texture_array */
-   if (screen->get_param(screen, PIPE_CAP_ARRAY_TEXTURES)) {
+   if (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) > 1) {
       ctx->Extensions.EXT_texture_array = GL_TRUE;
       ctx->Extensions.MESA_texture_array = GL_TRUE;
    }
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 9394bea00..892169822 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -519,7 +519,7 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
 
    inst->function = NULL;
    
-   if (op == TGSI_OPCODE_ARL)
+   if (op == TGSI_OPCODE_ARL || op == TGSI_OPCODE_UARL)
       this->num_address_regs = 1;
    
    /* Update indirect addressing status used by TGSI */
@@ -746,16 +746,12 @@ void
 glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
         		        st_dst_reg dst, st_src_reg src0)
 {
-   st_src_reg tmp = get_temp(glsl_type::float_type);
+   int op = TGSI_OPCODE_ARL;
 
-   if (src0.type == GLSL_TYPE_INT)
-      emit(NULL, TGSI_OPCODE_I2F, st_dst_reg(tmp), src0);
-   else if (src0.type == GLSL_TYPE_UINT)
-      emit(NULL, TGSI_OPCODE_U2F, st_dst_reg(tmp), src0);
-   else
-      tmp = src0;
-   
-   emit(NULL, TGSI_OPCODE_ARL, dst, tmp);
+   if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT)
+      op = TGSI_OPCODE_UARL;
+
+   emit(NULL, op, dst, src0);
 }
 
 /**
@@ -2558,6 +2554,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
       break;
    }
 
+   const glsl_type *sampler_type = ir->sampler->type;
+
    if (ir->projector) {
       if (opcode == TGSI_OPCODE_TEX) {
          /* Slot the projector in as the last component of the coord. */
@@ -2589,6 +2587,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
             tmp_src = get_temp(glsl_type::vec4_type);
             st_dst_reg tmp_dst = st_dst_reg(tmp_src);
 
+	    /* Projective division not allowed for array samplers. */
+	    assert(!sampler_type->sampler_array);
+
             tmp_dst.writemask = WRITEMASK_Z;
             emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result);
 
@@ -2613,7 +2614,15 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
        * coord.
        */
       ir->shadow_comparitor->accept(this);
-      coord_dst.writemask = WRITEMASK_Z;
+
+      /* XXX This will need to be updated for cubemap array samplers. */
+      if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
+          sampler_type->sampler_array) {
+         coord_dst.writemask = WRITEMASK_W;
+      } else {
+         coord_dst.writemask = WRITEMASK_Z;
+      }
+
       emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
       coord_dst.writemask = WRITEMASK_XYZW;
    }
@@ -2651,8 +2660,6 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
        inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2);
    }
 
-   const glsl_type *sampler_type = ir->sampler->type;
-
    switch (sampler_type->sampler_dimensionality) {
    case GLSL_SAMPLER_DIM_1D:
       inst->tex_target = (sampler_type->sampler_array)
diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
index f4263c64c..b4111b00d 100644
--- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -276,6 +276,8 @@ translate_texture_target( GLuint textarget,
       case TEXTURE_1D_INDEX:   return TGSI_TEXTURE_SHADOW1D;
       case TEXTURE_2D_INDEX:   return TGSI_TEXTURE_SHADOW2D;
       case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_SHADOWRECT;
+      case TEXTURE_1D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW1D_ARRAY;
+      case TEXTURE_2D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW2D_ARRAY;
       default: break;
       }
    }
diff --git a/mesalib/src/mesa/swrast/s_spantemp.h b/mesalib/src/mesa/swrast/s_spantemp.h
index 125d19638..517c2eb3f 100644
--- a/mesalib/src/mesa/swrast/s_spantemp.h
+++ b/mesalib/src/mesa/swrast/s_spantemp.h
@@ -1,221 +1,228 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.1
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/*
- * Templates for the span/pixel-array write/read functions called via
- * the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues
- * and PutMonoValues functions.
- *
- * Define the following macros before including this file:
- *   NAME(BASE)  to generate the function name (i.e. add prefix or suffix)
- *   RB_TYPE  the renderbuffer DataType
- *   SPAN_VARS  to declare any local variables
- *   INIT_PIXEL_PTR(P, X, Y)  to initialize a pointer to a pixel
- *   INC_PIXEL_PTR(P)  to increment a pixel pointer by one pixel
- *   STORE_PIXEL(DST, X, Y, VALUE)  to store pixel values in buffer
- *   FETCH_PIXEL(DST, SRC)  to fetch pixel values from buffer
- *
- * Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates
- * for the pixels to be stored.  This is useful when dithering and probably
- * ignored otherwise.
- */
-
-#include "main/macros.h"
-
-
-#if !defined(RB_COMPONENTS)
-#define RB_COMPONENTS 4
-#endif
-
-
-static void
-NAME(get_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
-               GLuint count, GLint x, GLint y, void *values )
-{
-#ifdef SPAN_VARS
-   SPAN_VARS
-#endif
-   RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
-   GLuint i;
-   INIT_PIXEL_PTR(pixel, x, y);
-   for (i = 0; i < count; i++) {
-      FETCH_PIXEL(dest[i], pixel);
-      INC_PIXEL_PTR(pixel);
-   }
-   (void) rb;
-}
-
-
-static void
-NAME(get_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
-                  GLuint count, const GLint x[], const GLint y[], void *values )
-{
-#ifdef SPAN_VARS
-   SPAN_VARS
-#endif
-   RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
-   GLuint i;
-   for (i = 0; i < count; i++) {
-      INIT_PIXEL_PTR(pixel, x[i], y[i]);
-      FETCH_PIXEL(dest[i], pixel);
-   }
-   (void) rb;
-}
-
-
-static void
-NAME(put_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
-               GLuint count, GLint x, GLint y,
-               const void *values, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
-   SPAN_VARS
-#endif
-   const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
-   GLuint i;
-   INIT_PIXEL_PTR(pixel, x, y);
-   if (mask) {
-      for (i = 0; i < count; i++) {
-         if (mask[i]) {
-            STORE_PIXEL(pixel, x + i, y, src[i]);
-         }
-         INC_PIXEL_PTR(pixel);
-      }
-   }
-   else {
-      for (i = 0; i < count; i++) {
-         STORE_PIXEL(pixel, x + i, y, src[i]);
-         INC_PIXEL_PTR(pixel);
-      }
-   }
-   (void) rb;
-}
-
-
-static void
-NAME(put_row_rgb)( struct gl_context *ctx, struct gl_renderbuffer *rb,
-                   GLuint count, GLint x, GLint y,
-                   const void *values, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
-   SPAN_VARS
-#endif
-   const RB_TYPE (*src)[3] = (const RB_TYPE (*)[3]) values;
-   GLuint i;
-   INIT_PIXEL_PTR(pixel, x, y);
-   for (i = 0; i < count; i++) {
-      if (!mask || mask[i]) {
-#ifdef STORE_PIXEL_RGB
-         STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
-#else
-         STORE_PIXEL(pixel, x + i, y, src[i]);
-#endif
-      }
-      INC_PIXEL_PTR(pixel);
-   }
-   (void) rb;
-}
-
-
-static void
-NAME(put_mono_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
-                    GLuint count, GLint x, GLint y,
-                    const void *value, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
-   SPAN_VARS
-#endif
-   const RB_TYPE *src = (const RB_TYPE *) value;
-   GLuint i;
-   INIT_PIXEL_PTR(pixel, x, y);
-   if (mask) {
-      for (i = 0; i < count; i++) {
-         if (mask[i]) {
-            STORE_PIXEL(pixel, x + i, y, src);
-         }
-         INC_PIXEL_PTR(pixel);
-      }
-   }
-   else {
-      for (i = 0; i < count; i++) {
-         STORE_PIXEL(pixel, x + i, y, src);
-         INC_PIXEL_PTR(pixel);
-      }
-   }
-   (void) rb;
-}
-
-
-static void
-NAME(put_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
-                  GLuint count, const GLint x[], const GLint y[],
-                  const void *values, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
-   SPAN_VARS
-#endif
-   const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
-   GLuint i;
-   ASSERT(mask);
-   for (i = 0; i < count; i++) {
-      if (mask[i]) {
-         INIT_PIXEL_PTR(pixel, x[i], y[i]);
-         STORE_PIXEL(pixel, x[i], y[i], src[i]);
-      }
-   }
-   (void) rb;
-}
-
-
-static void
-NAME(put_mono_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
-                       GLuint count, const GLint x[], const GLint y[],
-                       const void *value, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
-   SPAN_VARS
-#endif
-   const RB_TYPE *src = (const RB_TYPE *) value;
-   GLuint i;
-   ASSERT(mask);
-   for (i = 0; i < count; i++) {
-      if (mask[i]) {
-         INIT_PIXEL_PTR(pixel, x[i], y[i]);
-         STORE_PIXEL(pixel, x[i], y[i], src);
-      }
-   }
-   (void) rb;
-}
-
-
-#undef NAME
-#undef RB_TYPE
-#undef RB_COMPONENTS
-#undef SPAN_VARS
-#undef INIT_PIXEL_PTR
-#undef INC_PIXEL_PTR
-#undef STORE_PIXEL
-#undef STORE_PIXEL_RGB
-#undef FETCH_PIXEL
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.1
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Templates for the span/pixel-array write/read functions called via
+ * the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues
+ * and PutMonoValues functions.
+ *
+ * Define the following macros before including this file:
+ *   NAME(BASE)  to generate the function name (i.e. add prefix or suffix)
+ *   RB_TYPE  the renderbuffer DataType
+ *   SPAN_VARS  to declare any local variables
+ *   INIT_PIXEL_PTR(P, X, Y)  to initialize a pointer to a pixel
+ *   INC_PIXEL_PTR(P)  to increment a pixel pointer by one pixel
+ *   STORE_PIXEL(DST, X, Y, VALUE)  to store pixel values in buffer
+ *   FETCH_PIXEL(DST, SRC)  to fetch pixel values from buffer
+ *
+ * Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates
+ * for the pixels to be stored.  This is useful when dithering and probably
+ * ignored otherwise.
+ */
+
+#include "main/macros.h"
+
+
+#if !defined(RB_COMPONENTS)
+#define RB_COMPONENTS 4
+#endif
+
+
+static void
+NAME(get_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+               GLuint count, GLint x, GLint y, void *values )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
+   GLuint i;
+   INIT_PIXEL_PTR(pixel, x, y);
+   for (i = 0; i < count; i++) {
+      FETCH_PIXEL(dest[i], pixel);
+      INC_PIXEL_PTR(pixel);
+   }
+   (void) rb;
+   (void) ctx;
+}
+
+
+static void
+NAME(get_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+                  GLuint count, const GLint x[], const GLint y[], void *values )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
+   GLuint i;
+   for (i = 0; i < count; i++) {
+      INIT_PIXEL_PTR(pixel, x[i], y[i]);
+      FETCH_PIXEL(dest[i], pixel);
+   }
+   (void) rb;
+   (void) ctx;
+}
+
+
+static void
+NAME(put_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+               GLuint count, GLint x, GLint y,
+               const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
+   GLuint i;
+   INIT_PIXEL_PTR(pixel, x, y);
+   if (mask) {
+      for (i = 0; i < count; i++) {
+         if (mask[i]) {
+            STORE_PIXEL(pixel, x + i, y, src[i]);
+         }
+         INC_PIXEL_PTR(pixel);
+      }
+   }
+   else {
+      for (i = 0; i < count; i++) {
+         STORE_PIXEL(pixel, x + i, y, src[i]);
+         INC_PIXEL_PTR(pixel);
+      }
+   }
+   (void) rb;
+   (void) ctx;
+}
+
+
+static void
+NAME(put_row_rgb)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+                   GLuint count, GLint x, GLint y,
+                   const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE (*src)[3] = (const RB_TYPE (*)[3]) values;
+   GLuint i;
+   INIT_PIXEL_PTR(pixel, x, y);
+   for (i = 0; i < count; i++) {
+      if (!mask || mask[i]) {
+#ifdef STORE_PIXEL_RGB
+         STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
+#else
+         STORE_PIXEL(pixel, x + i, y, src[i]);
+#endif
+      }
+      INC_PIXEL_PTR(pixel);
+   }
+   (void) rb;
+   (void) ctx;
+}
+
+
+static void
+NAME(put_mono_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+                    GLuint count, GLint x, GLint y,
+                    const void *value, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE *src = (const RB_TYPE *) value;
+   GLuint i;
+   INIT_PIXEL_PTR(pixel, x, y);
+   if (mask) {
+      for (i = 0; i < count; i++) {
+         if (mask[i]) {
+            STORE_PIXEL(pixel, x + i, y, src);
+         }
+         INC_PIXEL_PTR(pixel);
+      }
+   }
+   else {
+      for (i = 0; i < count; i++) {
+         STORE_PIXEL(pixel, x + i, y, src);
+         INC_PIXEL_PTR(pixel);
+      }
+   }
+   (void) rb;
+   (void) ctx;
+}
+
+
+static void
+NAME(put_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+                  GLuint count, const GLint x[], const GLint y[],
+                  const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
+   GLuint i;
+   ASSERT(mask);
+   for (i = 0; i < count; i++) {
+      if (mask[i]) {
+         INIT_PIXEL_PTR(pixel, x[i], y[i]);
+         STORE_PIXEL(pixel, x[i], y[i], src[i]);
+      }
+   }
+   (void) rb;
+   (void) ctx;
+}
+
+
+static void
+NAME(put_mono_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+                       GLuint count, const GLint x[], const GLint y[],
+                       const void *value, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+   SPAN_VARS
+#endif
+   const RB_TYPE *src = (const RB_TYPE *) value;
+   GLuint i;
+   ASSERT(mask);
+   for (i = 0; i < count; i++) {
+      if (mask[i]) {
+         INIT_PIXEL_PTR(pixel, x[i], y[i]);
+         STORE_PIXEL(pixel, x[i], y[i], src);
+      }
+   }
+   (void) rb;
+   (void) ctx;
+}
+
+
+#undef NAME
+#undef RB_TYPE
+#undef RB_COMPONENTS
+#undef SPAN_VARS
+#undef INIT_PIXEL_PTR
+#undef INC_PIXEL_PTR
+#undef STORE_PIXEL
+#undef STORE_PIXEL_RGB
+#undef FETCH_PIXEL
diff --git a/pixman/configure.ac b/pixman/configure.ac
index 4c62102be..21613e135 100644
--- a/pixman/configure.ac
+++ b/pixman/configure.ac
@@ -54,7 +54,7 @@ AC_PREREQ([2.57])
 
 m4_define([pixman_major], 0)
 m4_define([pixman_minor], 23)
-m4_define([pixman_micro], 3)
+m4_define([pixman_micro], 5)
 
 m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro])
 
@@ -801,6 +801,17 @@ fi
 AC_MSG_RESULT($support_for_attribute_constructor)
 AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR)
 
+dnl ==================
+dnl libpng
+
+AC_CHECK_LIB([png], [png_write_info], [have_libpng=yes], [have_libpng=no])
+
+if test x$have_libpng = xyes; then
+    AC_DEFINE([HAVE_LIBPNG], [1], [Whether we have libpng])
+fi
+
+AC_SUBST(HAVE_LIBPNG)
+
 AC_OUTPUT([pixman-1.pc
            pixman-1-uninstalled.pc
            Makefile
diff --git a/pixman/pixman/pixman-arm-neon-asm.S b/pixman/pixman/pixman-arm-neon-asm.S
index 3dc14d79d..3fcd07dc3 100644
--- a/pixman/pixman/pixman-arm-neon-asm.S
+++ b/pixman/pixman/pixman-arm-neon-asm.S
@@ -706,13 +706,55 @@ generate_composite_function_single_scanline \
 
 /******************************************************************************/
 
-/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_n_8888_process_pixblock_head
+    /* deinterleaved source pixels in {d0, d1, d2, d3} */
+    /* inverted alpha in {d24} */
+    /* destination pixels in {d4, d5, d6, d7} */
+    vmull.u8    q8, d24, d4
+    vmull.u8    q9, d24, d5
+    vmull.u8    q10, d24, d6
+    vmull.u8    q11, d24, d7
+.endm
+
+.macro pixman_composite_over_n_8888_process_pixblock_tail
+    vrshr.u16   q14, q8, #8
+    vrshr.u16   q15, q9, #8
+    vrshr.u16   q2, q10, #8
+    vrshr.u16   q3, q11, #8
+    vraddhn.u16 d28, q14, q8
+    vraddhn.u16 d29, q15, q9
+    vraddhn.u16 d30, q2, q10
+    vraddhn.u16 d31, q3, q11
+    vqadd.u8    q14, q0, q14
+    vqadd.u8    q15, q1, q15
+.endm
+
 .macro pixman_composite_over_n_8888_process_pixblock_tail_head
-    pixman_composite_over_8888_8888_process_pixblock_tail
+        vrshr.u16   q14, q8, #8
+        vrshr.u16   q15, q9, #8
+        vrshr.u16   q2, q10, #8
+        vrshr.u16   q3, q11, #8
+        vraddhn.u16 d28, q14, q8
+        vraddhn.u16 d29, q15, q9
+        vraddhn.u16 d30, q2, q10
+        vraddhn.u16 d31, q3, q11
     vld4.8      {d4, d5, d6, d7}, [DST_R, :128]!
-    vst4.8      {d28, d29, d30, d31}, [DST_W, :128]!
-    pixman_composite_over_8888_8888_process_pixblock_head
-    cache_preload 8, 8
+        vqadd.u8    q14, q0, q14
+                                    PF add PF_X, PF_X, #8
+                                    PF tst PF_CTL, #0x0F
+                                    PF addne PF_X, PF_X, #8
+                                    PF subne PF_CTL, PF_CTL, #1
+        vqadd.u8    q15, q1, q15
+                                    PF cmp PF_X, ORIG_W
+    vmull.u8    q8, d24, d4
+                                    PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
+    vmull.u8    q9, d24, d5
+                                    PF subge PF_X, PF_X, ORIG_W
+    vmull.u8    q10, d24, d6
+                                    PF subges PF_CTL, PF_CTL, #0x10
+    vmull.u8    q11, d24, d7
+                                    PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
+        vst4.8      {d28, d29, d30, d31}, [DST_W, :128]!
 .endm
 
 .macro pixman_composite_over_n_8888_init
@@ -722,6 +764,7 @@ generate_composite_function_single_scanline \
     vdup.8      d1, d3[1]
     vdup.8      d2, d3[2]
     vdup.8      d3, d3[3]
+    vmvn.8      d24, d3  /* get inverted alpha */
 .endm
 
 generate_composite_function \
@@ -1183,49 +1226,83 @@ generate_composite_function \
     /* mask is in d24 (d25, d26, d27 are unused) */
 
     /* in */
-    vmull.u8    q0, d24, d8
-    vmull.u8    q1, d24, d9
-    vmull.u8    q6, d24, d10
-    vmull.u8    q7, d24, d11
-    vrshr.u16   q10, q0, #8
-    vrshr.u16   q11, q1, #8
-    vrshr.u16   q12, q6, #8
-    vrshr.u16   q13, q7, #8
-    vraddhn.u16 d0, q0, q10
-    vraddhn.u16 d1, q1, q11
-    vraddhn.u16 d2, q6, q12
-    vraddhn.u16 d3, q7, q13
-    vmvn.8      d24, d3  /* get inverted alpha */
+    vmull.u8    q6, d24, d8
+    vmull.u8    q7, d24, d9
+    vmull.u8    q8, d24, d10
+    vmull.u8    q9, d24, d11
+    vrshr.u16   q10, q6, #8
+    vrshr.u16   q11, q7, #8
+    vrshr.u16   q12, q8, #8
+    vrshr.u16   q13, q9, #8
+    vraddhn.u16 d0, q6, q10
+    vraddhn.u16 d1, q7, q11
+    vraddhn.u16 d2, q8, q12
+    vraddhn.u16 d3, q9, q13
+    vmvn.8      d25, d3  /* get inverted alpha */
     /* source:      d0 - blue, d1 - green, d2 - red, d3 - alpha */
     /* destination: d4 - blue, d5 - green, d6 - red, d7 - alpha */
     /* now do alpha blending */
-    vmull.u8    q8, d24, d4
-    vmull.u8    q9, d24, d5
-    vmull.u8    q10, d24, d6
-    vmull.u8    q11, d24, d7
+    vmull.u8    q8, d25, d4
+    vmull.u8    q9, d25, d5
+    vmull.u8    q10, d25, d6
+    vmull.u8    q11, d25, d7
 .endm
 
 .macro pixman_composite_over_n_8_8888_process_pixblock_tail
     vrshr.u16   q14, q8, #8
     vrshr.u16   q15, q9, #8
-    vrshr.u16   q12, q10, #8
-    vrshr.u16   q13, q11, #8
+    vrshr.u16   q6, q10, #8
+    vrshr.u16   q7, q11, #8
     vraddhn.u16 d28, q14, q8
     vraddhn.u16 d29, q15, q9
-    vraddhn.u16 d30, q12, q10
-    vraddhn.u16 d31, q13, q11
+    vraddhn.u16 d30, q6, q10
+    vraddhn.u16 d31, q7, q11
     vqadd.u8    q14, q0, q14
     vqadd.u8    q15, q1, q15
 .endm
 
-/* TODO: expand macros and do better instructions scheduling */
 .macro pixman_composite_over_n_8_8888_process_pixblock_tail_head
-    pixman_composite_over_n_8_8888_process_pixblock_tail
-    vst4.8      {d28, d29, d30, d31}, [DST_W, :128]!
+        vrshr.u16   q14, q8, #8
     vld4.8      {d4, d5, d6, d7}, [DST_R, :128]!
+        vrshr.u16   q15, q9, #8
     fetch_mask_pixblock
-    cache_preload 8, 8
-    pixman_composite_over_n_8_8888_process_pixblock_head
+        vrshr.u16   q6, q10, #8
+                                    PF add PF_X, PF_X, #8
+        vrshr.u16   q7, q11, #8
+                                    PF tst PF_CTL, #0x0F
+        vraddhn.u16 d28, q14, q8
+                                    PF addne PF_X, PF_X, #8
+        vraddhn.u16 d29, q15, q9
+                                    PF subne PF_CTL, PF_CTL, #1
+        vraddhn.u16 d30, q6, q10
+                                    PF cmp PF_X, ORIG_W
+        vraddhn.u16 d31, q7, q11
+                                    PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
+    vmull.u8    q6, d24, d8
+                                    PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift]
+    vmull.u8    q7, d24, d9
+                                    PF subge PF_X, PF_X, ORIG_W
+    vmull.u8    q8, d24, d10
+                                    PF subges PF_CTL, PF_CTL, #0x10
+    vmull.u8    q9, d24, d11
+                                    PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
+        vqadd.u8    q14, q0, q14
+                                    PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]!
+        vqadd.u8    q15, q1, q15
+    vrshr.u16   q10, q6, #8
+    vrshr.u16   q11, q7, #8
+    vrshr.u16   q12, q8, #8
+    vrshr.u16   q13, q9, #8
+    vraddhn.u16 d0, q6, q10
+    vraddhn.u16 d1, q7, q11
+    vraddhn.u16 d2, q8, q12
+    vraddhn.u16 d3, q9, q13
+        vst4.8      {d28, d29, d30, d31}, [DST_W, :128]!
+    vmvn.8      d25, d3
+    vmull.u8    q8, d25, d4
+    vmull.u8    q9, d25, d5
+    vmull.u8    q10, d25, d6
+    vmull.u8    q11, d25, d7
 .endm
 
 .macro pixman_composite_over_n_8_8888_init
diff --git a/pixman/pixman/pixman-bits-image.c b/pixman/pixman/pixman-bits-image.c
index f540c76e1..f382c65ad 100644
--- a/pixman/pixman/pixman-bits-image.c
+++ b/pixman/pixman/pixman-bits-image.c
@@ -935,17 +935,16 @@ MAKE_FETCHERS (reflect_r5g6b5,   r5g6b5,   PIXMAN_REPEAT_REFLECT)
 MAKE_FETCHERS (normal_r5g6b5,    r5g6b5,   PIXMAN_REPEAT_NORMAL)
 
 static void
-bits_image_fetch_solid_32 (pixman_image_t * image,
-                           int              x,
-                           int              y,
-                           int              width,
-                           uint32_t *       buffer,
-                           const uint32_t * mask)
+replicate_pixel_32 (bits_image_t *   bits,
+		    int              x,
+		    int              y,
+		    int              width,
+		    uint32_t *       buffer)
 {
     uint32_t color;
     uint32_t *end;
 
-    color = image->bits.fetch_pixel_32 (&image->bits, 0, 0);
+    color = bits->fetch_pixel_32 (bits, x, y);
 
     end = buffer + width;
     while (buffer < end)
@@ -953,24 +952,45 @@ bits_image_fetch_solid_32 (pixman_image_t * image,
 }
 
 static void
-bits_image_fetch_solid_64 (pixman_image_t * image,
-                           int              x,
-                           int              y,
-                           int              width,
-                           uint32_t *       b,
-                           const uint32_t * unused)
+replicate_pixel_64 (bits_image_t *   bits,
+		    int              x,
+		    int              y,
+		    int              width,
+		    uint32_t *       b)
 {
     uint64_t color;
     uint64_t *buffer = (uint64_t *)b;
     uint64_t *end;
 
-    color = image->bits.fetch_pixel_64 (&image->bits, 0, 0);
+    color = bits->fetch_pixel_64 (bits, x, y);
 
     end = buffer + width;
     while (buffer < end)
 	*(buffer++) = color;
 }
 
+static void
+bits_image_fetch_solid_32 (pixman_image_t * image,
+                           int              x,
+                           int              y,
+                           int              width,
+                           uint32_t *       buffer,
+                           const uint32_t * mask)
+{
+    replicate_pixel_32 (&image->bits, 0, 0, width, buffer);
+}
+
+static void
+bits_image_fetch_solid_64 (pixman_image_t * image,
+                           int              x,
+                           int              y,
+                           int              width,
+                           uint32_t *       b,
+                           const uint32_t * unused)
+{
+    replicate_pixel_64 (&image->bits, 0, 0, width, b);
+}
+
 static void
 bits_image_fetch_untransformed_repeat_none (bits_image_t *image,
                                             pixman_bool_t wide,
@@ -1031,6 +1051,16 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
     while (y >= image->height)
 	y -= image->height;
 
+    if (image->width == 1)
+    {
+	if (wide)
+	    replicate_pixel_64 (image, 0, y, width, buffer);
+	else
+	    replicate_pixel_32 (image, 0, y, width, buffer);
+
+	return;
+    }
+
     while (width)
     {
 	while (x < 0)
diff --git a/pixman/test/Makefile.am b/pixman/test/Makefile.am
index 9f61fc9e4..52ef8ad96 100644
--- a/pixman/test/Makefile.am
+++ b/pixman/test/Makefile.am
@@ -1,6 +1,6 @@
 AM_CFLAGS = @OPENMP_CFLAGS@
 AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
-LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
+LDADD = $(top_builddir)/pixman/libpixman-1.la -lm -lpng
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
 
 TESTPROGRAMS =			\
diff --git a/pixman/test/utils.c b/pixman/test/utils.c
index 44188ea90..adabd75dd 100644
--- a/pixman/test/utils.c
+++ b/pixman/test/utils.c
@@ -21,6 +21,10 @@
 #include <fenv.h>
 #endif
 
+#ifdef HAVE_LIBPNG
+#include <png.h>
+#endif
+
 /* Random number seed
  */
 
@@ -335,6 +339,114 @@ make_random_bytes (int n_bytes)
     return bytes;
 }
 
+#ifdef HAVE_LIBPNG
+
+static void
+pngify_pixels (uint32_t *pixels, int n_pixels)
+{
+    int i;
+
+    for (i = 0; i < n_pixels; ++i)
+    {
+	uint32_t p = pixels[i];
+	uint8_t *out = (uint8_t *)&(pixels[i]);
+	uint8_t a, r, g, b;
+
+	a = (p & 0xff000000) >> 24;
+	r = (p & 0x00ff0000) >> 16;
+	g = (p & 0x0000ff00) >> 8;
+	b = (p & 0x000000ff) >> 0;
+
+	if (a != 0)
+	{
+	    r = (r * 255) / a;
+	    g = (g * 255) / a;
+	    b = (b * 255) / a;
+	}
+
+	*out++ = r;
+	*out++ = g;
+	*out++ = b;
+	*out++ = a;
+    }
+}
+
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename)
+{
+    int width = pixman_image_get_width (image);
+    int height = pixman_image_get_height (image);
+    int stride = width * 4;
+    uint32_t *data = malloc (height * stride);
+    pixman_image_t *copy;
+    png_struct *write_struct;
+    png_info *info_struct;
+    pixman_bool_t result = FALSE;
+    FILE *f = fopen (filename, "wb");
+    png_bytep *row_pointers;
+    int i;
+
+    if (!f)
+	return FALSE;
+
+    row_pointers = malloc (height * sizeof (png_bytep));
+
+    copy = pixman_image_create_bits (
+	PIXMAN_a8r8g8b8, width, height, data, stride);
+
+    pixman_image_composite32 (
+	PIXMAN_OP_SRC, image, NULL, copy, 0, 0, 0, 0, 0, 0, width, height);
+
+    pngify_pixels (data, height * width);
+
+    for (i = 0; i < height; ++i)
+	row_pointers[i] = (png_bytep)(data + i * width);
+
+    if (!(write_struct = png_create_write_struct (
+	      PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
+	goto out1;
+
+    if (!(info_struct = png_create_info_struct (write_struct)))
+	goto out2;
+
+    png_init_io (write_struct, f);
+
+    png_set_IHDR (write_struct, info_struct, width, height,
+		  8, PNG_COLOR_TYPE_RGB_ALPHA,
+		  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
+		  PNG_FILTER_TYPE_BASE);
+
+    png_write_info (write_struct, info_struct);
+
+    png_write_image (write_struct, row_pointers);
+
+    png_write_end (write_struct, NULL);
+
+    result = TRUE;
+
+out2:
+    png_destroy_write_struct (&write_struct, &info_struct);
+
+out1:
+    if (fclose (f) != 0)
+	result = FALSE;
+
+    pixman_image_unref (copy);
+    free (row_pointers);
+    free (data);
+    return result;
+}
+
+#else /* no libpng */
+
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename)
+{
+    return FALSE;
+}
+
+#endif
+
 /*
  * A function, which can be used as a core part of the test programs,
  * intended to detect various problems with the help of fuzzing input
diff --git a/pixman/test/utils.h b/pixman/test/utils.h
index f0c9c300c..3790483db 100644
--- a/pixman/test/utils.h
+++ b/pixman/test/utils.h
@@ -105,6 +105,9 @@ fail_after (int seconds, const char *msg);
 /* If possible, enable traps for floating point exceptions */
 void enable_fp_exceptions(void);
 
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename);
+
 /* A pair of macros which can help to detect corruption of
  * floating point registers after a function call. This may
  * happen if _mm_empty() call is forgotten in MMX/SSE2 fast
-- 
cgit v1.2.3