From 2414a1de3cc17f438219f8f2a58b530d33e99a5e Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Fri, 6 Sep 2013 12:06:57 +0200
Subject: mesa pixman xserver xkeyboard-config

xserver          commit 6f89ae3e64c4dfeea508813e546c10ba1da3ea8e
xkeyboard-config commit c2309b50e7ef7b9263278fd8ff73dda1484d72db
pixman           commit 8ad63f90cd8392a40f115c56b16c54d45012070e
mesa             commit 505fad04f10eee1efdfcd8986b4d484b49d39986
---
 mesalib/src/glsl/glsl_parser.yy     |  10 +-
 mesalib/src/glsl/ir_clone.cpp       |   2 +
 mesalib/src/glsl/link_functions.cpp |  32 +++++
 mesalib/src/glsl/link_varyings.cpp  | 225 ++++++++++++++++++++++--------------
 mesalib/src/glsl/link_varyings.h    |   3 +-
 5 files changed, 182 insertions(+), 90 deletions(-)

(limited to 'mesalib/src/glsl')

diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index d8e589d49..fa6e2053a 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -1714,13 +1714,17 @@ struct_declaration_list:
    ;
 
 struct_declaration:
-   type_specifier struct_declarator_list ';'
+   fully_specified_type struct_declarator_list ';'
    {
       void *ctx = state;
-      ast_fully_specified_type *type = new(ctx) ast_fully_specified_type();
+      ast_fully_specified_type *const type = $1;
       type->set_location(yylloc);
 
-      type->specifier = $1;
+      if (type->qualifier.flags.i != 0)
+         _mesa_glsl_error(&@1, state,
+			  "only precision qualifiers may be applied to "
+			  "structure members");
+
       $$ = new(ctx) ast_declarator_list(type);
       $$->set_location(yylloc);
 
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index 9d4178de8..a75b3b762 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -59,6 +59,8 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
    var->explicit_binding = this->explicit_binding;
    var->has_initializer = this->has_initializer;
    var->depth_layout = this->depth_layout;
+   var->assigned = this->assigned;
+   var->used = this->used;
 
    var->num_state_slots = this->num_state_slots;
    if (this->state_slots) {
diff --git a/mesalib/src/glsl/link_functions.cpp b/mesalib/src/glsl/link_functions.cpp
index 6b3e15448..dd6f24716 100644
--- a/mesalib/src/glsl/link_functions.cpp
+++ b/mesalib/src/glsl/link_functions.cpp
@@ -173,6 +173,38 @@ public:
       return visit_continue;
    }
 
+   virtual ir_visitor_status visit_leave(ir_call *ir)
+   {
+      /* Traverse list of function parameters, and for array parameters
+       * propagate max_array_access. Otherwise arrays that are only referenced
+       * from inside functions via function parameters will be incorrectly
+       * optimized. This will lead to incorrect code being generated (or worse).
+       * Do it when leaving the node so the children would propagate their
+       * array accesses first.
+       */
+
+      const exec_node *formal_param_node = ir->callee->parameters.get_head();
+      if (formal_param_node) {
+         const exec_node *actual_param_node = ir->actual_parameters.get_head();
+         while (!actual_param_node->is_tail_sentinel()) {
+            ir_variable *formal_param = (ir_variable *) formal_param_node;
+            ir_rvalue *actual_param = (ir_rvalue *) actual_param_node;
+
+            formal_param_node = formal_param_node->get_next();
+            actual_param_node = actual_param_node->get_next();
+
+            if (formal_param->type->is_array()) {
+               ir_dereference_variable *deref = actual_param->as_dereference_variable();
+               if (deref && deref->var && deref->var->type->is_array()) {
+                  deref->var->max_array_access =
+                     MAX2(formal_param->max_array_access, deref->var->max_array_access);
+               }
+            }
+         }
+      }
+      return visit_continue;
+   }
+
    virtual ir_visitor_status visit(ir_dereference_variable *ir)
    {
       if (hash_table_find(locals, ir->var) == NULL) {
diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp
index 4ceb1d33e..081a51da5 100644
--- a/mesalib/src/glsl/link_varyings.cpp
+++ b/mesalib/src/glsl/link_varyings.cpp
@@ -40,6 +40,118 @@
 #include "program.h"
 
 
+/**
+ * Validate the types and qualifiers of an output from one stage against the
+ * matching input to another stage.
+ */
+static void
+cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
+                                    const ir_variable *input,
+                                    const ir_variable *output,
+                                    GLenum consumer_type,
+                                    GLenum producer_type)
+{
+   /* Check that the types match between stages.
+    */
+   const glsl_type *type_to_match = input->type;
+   if (consumer_type == GL_GEOMETRY_SHADER) {
+      assert(type_to_match->is_array()); /* Enforced by ast_to_hir */
+      type_to_match = type_to_match->element_type();
+   }
+   if (type_to_match != output->type) {
+      /* There is a bit of a special case for gl_TexCoord.  This
+       * built-in is unsized by default.  Applications that variable
+       * access it must redeclare it with a size.  There is some
+       * language in the GLSL spec that implies the fragment shader
+       * and vertex shader do not have to agree on this size.  Other
+       * driver behave this way, and one or two applications seem to
+       * rely on it.
+       *
+       * Neither declaration needs to be modified here because the array
+       * sizes are fixed later when update_array_sizes is called.
+       *
+       * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec:
+       *
+       *     "Unlike user-defined varying variables, the built-in
+       *     varying variables don't have a strict one-to-one
+       *     correspondence between the vertex language and the
+       *     fragment language."
+       */
+      if (!output->type->is_array()
+          || (strncmp("gl_", output->name, 3) != 0)) {
+         linker_error(prog,
+                      "%s shader output `%s' declared as type `%s', "
+                      "but %s shader input declared as type `%s'\n",
+                      _mesa_glsl_shader_target_name(producer_type),
+                      output->name,
+                      output->type->name,
+                      _mesa_glsl_shader_target_name(consumer_type),
+                      input->type->name);
+         return;
+      }
+   }
+
+   /* Check that all of the qualifiers match between stages.
+    */
+   if (input->centroid != output->centroid) {
+      linker_error(prog,
+                   "%s shader output `%s' %s centroid qualifier, "
+                   "but %s shader input %s centroid qualifier\n",
+                   _mesa_glsl_shader_target_name(producer_type),
+                   output->name,
+                   (output->centroid) ? "has" : "lacks",
+                   _mesa_glsl_shader_target_name(consumer_type),
+                   (input->centroid) ? "has" : "lacks");
+      return;
+   }
+
+   if (input->invariant != output->invariant) {
+      linker_error(prog,
+                   "%s shader output `%s' %s invariant qualifier, "
+                   "but %s shader input %s invariant qualifier\n",
+                   _mesa_glsl_shader_target_name(producer_type),
+                   output->name,
+                   (output->invariant) ? "has" : "lacks",
+                   _mesa_glsl_shader_target_name(consumer_type),
+                   (input->invariant) ? "has" : "lacks");
+      return;
+   }
+
+   if (input->interpolation != output->interpolation) {
+      linker_error(prog,
+                   "%s shader output `%s' specifies %s "
+                   "interpolation qualifier, "
+                   "but %s shader input specifies %s "
+                   "interpolation qualifier\n",
+                   _mesa_glsl_shader_target_name(producer_type),
+                   output->name,
+                   output->interpolation_string(),
+                   _mesa_glsl_shader_target_name(consumer_type),
+                   input->interpolation_string());
+      return;
+   }
+}
+
+/**
+ * Validate front and back color outputs against single color input
+ */
+static void
+cross_validate_front_and_back_color(struct gl_shader_program *prog,
+                                    const ir_variable *input,
+                                    const ir_variable *front_color,
+                                    const ir_variable *back_color,
+                                    GLenum consumer_type,
+                                    GLenum producer_type)
+{
+   if (front_color != NULL && front_color->assigned)
+      cross_validate_types_and_qualifiers(prog, input, front_color,
+                                          consumer_type, producer_type);
+
+   if (back_color != NULL && back_color->assigned)
+      cross_validate_types_and_qualifiers(prog, input, back_color,
+                                          consumer_type, producer_type);
+}
+
 /**
  * Validate that outputs from one stage match inputs of another
  */
@@ -48,10 +160,6 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
 				 gl_shader *producer, gl_shader *consumer)
 {
    glsl_symbol_table parameters;
-   const char *const producer_stage =
-      _mesa_glsl_shader_target_name(producer->Type);
-   const char *const consumer_stage =
-      _mesa_glsl_shader_target_name(consumer->Type);
 
    /* Find all shader outputs in the "producer" stage.
     */
@@ -79,85 +187,32 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
       if ((input == NULL) || (input->mode != ir_var_shader_in))
 	 continue;
 
-      ir_variable *const output = parameters.get_variable(input->name);
-      if (output != NULL) {
-	 /* Check that the types match between stages.
-	  */
-         const glsl_type *type_to_match = input->type;
-         if (consumer->Type == GL_GEOMETRY_SHADER) {
-            assert(type_to_match->is_array()); /* Enforced by ast_to_hir */
-            type_to_match = type_to_match->element_type();
+      if (strcmp(input->name, "gl_Color") == 0 && input->used) {
+         const ir_variable *const front_color =
+            parameters.get_variable("gl_FrontColor");
+
+         const ir_variable *const back_color =
+            parameters.get_variable("gl_BackColor");
+
+         cross_validate_front_and_back_color(prog, input,
+                                             front_color, back_color,
+                                             consumer->Type, producer->Type);
+      } else if (strcmp(input->name, "gl_SecondaryColor") == 0 && input->used) {
+         const ir_variable *const front_color =
+            parameters.get_variable("gl_FrontSecondaryColor");
+
+         const ir_variable *const back_color =
+            parameters.get_variable("gl_BackSecondaryColor");
+
+         cross_validate_front_and_back_color(prog, input,
+                                             front_color, back_color,
+                                             consumer->Type, producer->Type);
+      } else {
+         ir_variable *const output = parameters.get_variable(input->name);
+         if (output != NULL) {
+            cross_validate_types_and_qualifiers(prog, input, output,
+                                                consumer->Type, producer->Type);
          }
-	 if (type_to_match != output->type) {
-	    /* There is a bit of a special case for gl_TexCoord.  This
-	     * built-in is unsized by default.  Applications that variable
-	     * access it must redeclare it with a size.  There is some
-	     * language in the GLSL spec that implies the fragment shader
-	     * and vertex shader do not have to agree on this size.  Other
-	     * driver behave this way, and one or two applications seem to
-	     * rely on it.
-	     *
-	     * Neither declaration needs to be modified here because the array
-	     * sizes are fixed later when update_array_sizes is called.
-	     *
-	     * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec:
-	     *
-	     *     "Unlike user-defined varying variables, the built-in
-	     *     varying variables don't have a strict one-to-one
-	     *     correspondence between the vertex language and the
-	     *     fragment language."
-	     */
-	    if (!output->type->is_array()
-		|| (strncmp("gl_", output->name, 3) != 0)) {
-	       linker_error(prog,
-			    "%s shader output `%s' declared as type `%s', "
-			    "but %s shader input declared as type `%s'\n",
-			    producer_stage, output->name,
-			    output->type->name,
-			    consumer_stage, input->type->name);
-	       return;
-	    }
-	 }
-
-	 /* Check that all of the qualifiers match between stages.
-	  */
-	 if (input->centroid != output->centroid) {
-	    linker_error(prog,
-			 "%s shader output `%s' %s centroid qualifier, "
-			 "but %s shader input %s centroid qualifier\n",
-			 producer_stage,
-			 output->name,
-			 (output->centroid) ? "has" : "lacks",
-			 consumer_stage,
-			 (input->centroid) ? "has" : "lacks");
-	    return;
-	 }
-
-	 if (input->invariant != output->invariant) {
-	    linker_error(prog,
-			 "%s shader output `%s' %s invariant qualifier, "
-			 "but %s shader input %s invariant qualifier\n",
-			 producer_stage,
-			 output->name,
-			 (output->invariant) ? "has" : "lacks",
-			 consumer_stage,
-			 (input->invariant) ? "has" : "lacks");
-	    return;
-	 }
-
-	 if (input->interpolation != output->interpolation) {
-	    linker_error(prog,
-			 "%s shader output `%s' specifies %s "
-			 "interpolation qualifier, "
-			 "but %s shader input specifies %s "
-			 "interpolation qualifier\n",
-			 producer_stage,
-			 output->name,
-			 output->interpolation_string(),
-			 consumer_stage,
-			 input->interpolation_string());
-	    return;
-	 }
       }
    }
 }
@@ -172,8 +227,8 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
  * will fail to find any matching variable.
  */
 void
-tfeedback_decl::init(struct gl_context *ctx, struct gl_shader_program *prog,
-                     const void *mem_ctx, const char *input)
+tfeedback_decl::init(struct gl_context *ctx, const void *mem_ctx,
+                     const char *input)
 {
    /* We don't have to be pedantic about what is a valid GLSL variable name,
     * because any variable with an invalid name can't exist in the IR anyway.
@@ -443,7 +498,7 @@ parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog,
                       char **varying_names, tfeedback_decl *decls)
 {
    for (unsigned i = 0; i < num_names; ++i) {
-      decls[i].init(ctx, prog, mem_ctx, varying_names[i]);
+      decls[i].init(ctx, mem_ctx, varying_names[i]);
 
       if (!decls[i].is_varying())
          continue;
diff --git a/mesalib/src/glsl/link_varyings.h b/mesalib/src/glsl/link_varyings.h
index 302ab5c26..6264ef05b 100644
--- a/mesalib/src/glsl/link_varyings.h
+++ b/mesalib/src/glsl/link_varyings.h
@@ -91,8 +91,7 @@ struct tfeedback_candidate
 class tfeedback_decl
 {
 public:
-   void init(struct gl_context *ctx, struct gl_shader_program *prog,
-             const void *mem_ctx, const char *input);
+   void init(struct gl_context *ctx, const void *mem_ctx, const char *input);
    static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y);
    bool assign_location(struct gl_context *ctx,
                         struct gl_shader_program *prog);
-- 
cgit v1.2.3