From 49838240b7d4cff1ffed1bd91e495f6919061f90 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Wed, 1 Aug 2012 08:02:35 +0200
Subject: git mesa update 1 Aug 2012

---
 mesalib/src/glsl/ast.h                  | 23 ++++++++++++
 mesalib/src/glsl/ast_type.cpp           | 45 +++++++++++++++++++++++
 mesalib/src/glsl/glsl_parser.yy         | 65 ++++++++++++++++++++-------------
 mesalib/src/glsl/glsl_parser_extras.cpp | 18 +++------
 mesalib/src/glsl/glsl_parser_extras.h   | 24 ++++--------
 mesalib/src/glsl/link_uniforms.cpp      | 19 ++++++++--
 mesalib/src/glsl/linker.cpp             | 34 +++++++++++++++++
 7 files changed, 169 insertions(+), 59 deletions(-)

(limited to 'mesalib/src/glsl')

diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h
index de3f2dfeb..50747822d 100644
--- a/mesalib/src/glsl/ast.h
+++ b/mesalib/src/glsl/ast.h
@@ -338,6 +338,25 @@ enum {
 };
 
 struct ast_type_qualifier {
+   /* Callers of this ralloc-based new need not call delete. It's
+    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
+   static void* operator new(size_t size, void *ctx)
+   {
+      void *node;
+
+      node = rzalloc_size(ctx, size);
+      assert(node != NULL);
+
+      return node;
+   }
+
+   /* If the user *does* call delete, that's OK, we will just
+    * ralloc_free in that case. */
+   static void operator delete(void *table)
+   {
+      ralloc_free(table);
+   }
+
    union {
       struct {
 	 unsigned invariant:1;
@@ -424,6 +443,10 @@ struct ast_type_qualifier {
     * returned string is undefined but not null.
     */
    const char *interpolation_string() const;
+
+   bool merge_qualifier(YYLTYPE *loc,
+			_mesa_glsl_parse_state *state,
+			ast_type_qualifier q);
 };
 
 class ast_declarator_list;
diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp
index 6c44f8c41..29493e2f6 100644
--- a/mesalib/src/glsl/ast_type.cpp
+++ b/mesalib/src/glsl/ast_type.cpp
@@ -71,3 +71,48 @@ ast_type_qualifier::interpolation_string() const
    else
       return NULL;
 }
+
+bool
+ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
+				    _mesa_glsl_parse_state *state,
+				    ast_type_qualifier q)
+{
+   ast_type_qualifier ubo_mat_mask;
+   ubo_mat_mask.flags.i = 0;
+   ubo_mat_mask.flags.q.row_major = 1;
+   ubo_mat_mask.flags.q.column_major = 1;
+
+   ast_type_qualifier ubo_layout_mask;
+   ubo_layout_mask.flags.i = 0;
+   ubo_layout_mask.flags.q.std140 = 1;
+   ubo_layout_mask.flags.q.packed = 1;
+   ubo_layout_mask.flags.q.shared = 1;
+
+   /* Uniform block layout qualifiers get to overwrite each
+    * other (rightmost having priority), while all other
+    * qualifiers currently don't allow duplicates.
+    */
+
+   if ((this->flags.i & q.flags.i & ~(ubo_mat_mask.flags.i |
+				      ubo_layout_mask.flags.i)) != 0) {
+      _mesa_glsl_error(loc, state,
+		       "duplicate layout qualifiers used\n");
+      return false;
+   }
+
+   if ((q.flags.i & ubo_mat_mask.flags.i) != 0)
+      this->flags.i &= ~ubo_mat_mask.flags.i;
+   if ((q.flags.i & ubo_layout_mask.flags.i) != 0)
+      this->flags.i &= ~ubo_layout_mask.flags.i;
+
+   this->flags.i |= q.flags.i;
+
+   if (q.flags.q.explicit_location)
+      this->location = q.location;
+
+   if (q.flags.q.explicit_index)
+      this->index = q.index;
+
+   return true;
+}
+
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index f61d6b8dd..04c64f096 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -29,6 +29,7 @@
 #include "ast.h"
 #include "glsl_parser_extras.h"
 #include "glsl_types.h"
+#include "main/context.h"
 
 #define YYLEX_PARAM state->scanner
 
@@ -259,19 +260,25 @@ version_statement:
 	   switch ($2) {
 	   case 100:
 	      state->es_shader = true;
-	      supported = state->Const.GLSL_100ES;
+	      supported = state->ctx->API == API_OPENGLES2 ||
+		          state->ctx->Extensions.ARB_ES2_compatibility;
 	      break;
 	   case 110:
-	      supported = state->Const.GLSL_110;
-	      break;
 	   case 120:
-	      supported = state->Const.GLSL_120;
-	      break;
+	      /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or
+	       * the OpenGL 3.2 Core context is supported, this logic will need
+	       * change.  Older versions of GLSL are no longer supported
+	       * outside the compatibility contexts of 3.x.
+	       */
 	   case 130:
-	      supported = state->Const.GLSL_130;
-	      break;
 	   case 140:
-	      supported = state->Const.GLSL_140;
+	   case 150:
+	   case 330:
+	   case 400:
+	   case 410:
+	   case 420:
+	      supported = _mesa_is_desktop_gl(state->ctx) &&
+			  ((unsigned) $2) <= state->ctx->Const.GLSLVersion;
 	      break;
 	   default:
 	      supported = false;
@@ -291,6 +298,10 @@ version_statement:
 			       state->version_string,
 			       state->supported_version_string);
 	   }
+
+	   if (state->language_version >= 140) {
+	      state->ARB_uniform_buffer_object_enable = true;
+	   }
 	}
 	;
 
@@ -301,7 +312,7 @@ pragma_statement:
 	| PRAGMA_OPTIMIZE_OFF EOL
 	| PRAGMA_INVARIANT_ALL EOL
 	{
-	   if (state->language_version < 120 && !state->Const.GLSL_100ES) {
+	   if (state->language_version == 110) {
 	      _mesa_glsl_warning(& @1, state,
 				 "pragma `invariant(all)' not supported in %s",
 				 state->version_string);
@@ -1102,20 +1113,10 @@ layout_qualifier_id_list:
 	layout_qualifier_id
 	| layout_qualifier_id_list ',' layout_qualifier_id
 	{
-	   if (($1.flags.i & $3.flags.i) != 0) {
-	      _mesa_glsl_error(& @3, state,
-			       "duplicate layout qualifiers used\n");
+	   $$ = $1;
+	   if (!$$.merge_qualifier(& @3, state, $3)) {
 	      YYERROR;
 	   }
-
-	   $$ = $1;
-	   $$.flags.i |= $3.flags.i;
-
-	   if ($3.flags.q.explicit_location)
-	      $$.location = $3.location;
-
-	   if ($3.flags.q.explicit_index)
-	      $$.index = $3.index;
 	}
 	;
 
@@ -1905,6 +1906,7 @@ external_declaration:
 	function_definition	{ $$ = $1; }
 	| declaration		{ $$ = $1; }
 	| pragma_statement	{ $$ = NULL; }
+	| layout_defaults	{ $$ = NULL; }
 	;
 
 function_definition:
@@ -1925,14 +1927,18 @@ uniform_block:
 	UNIFORM NEW_IDENTIFIER '{' member_list '}' ';'
 	{
 	   void *ctx = state;
-	   ast_type_qualifier no_qual;
-	   memset(&no_qual, 0, sizeof(no_qual));
-	   $$ = new(ctx) ast_uniform_block(no_qual, $2, $4);
+	   $$ = new(ctx) ast_uniform_block(*state->default_uniform_qualifier,
+					   $2, $4);
 	}
 	| layout_qualifier UNIFORM NEW_IDENTIFIER '{' member_list '}' ';'
 	{
 	   void *ctx = state;
-	   $$ = new(ctx) ast_uniform_block($1, $3, $5);
+
+	   ast_type_qualifier qual = *state->default_uniform_qualifier;
+	   if (!qual.merge_qualifier(& @1, state, $1)) {
+	      YYERROR;
+	   }
+	   $$ = new(ctx) ast_uniform_block(qual, $3, $5);
 	}
 	;
 
@@ -1986,3 +1992,12 @@ member_declaration:
 	   $$->declarations.push_degenerate_list_at_head(& $3->link);
 	}
 	;
+
+layout_defaults:
+	layout_qualifier UNIFORM ';'
+	{
+	   if (!state->default_uniform_qualifier->merge_qualifier(& @1, state,
+								  $1)) {
+	      YYERROR;
+	   }
+	}
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index 7a9b22197..09e1e590d 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -85,23 +85,11 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
 
    this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
 
-   /* Note: Once the OpenGL 3.0 'forward compatible' context or the OpenGL 3.2
-    * Core context is supported, this logic will need change.  Older versions of
-    * GLSL are no longer supported outside the compatibility contexts of 3.x.
-    */
-   this->Const.GLSL_100ES = (ctx->API == API_OPENGLES2)
-      || ctx->Extensions.ARB_ES2_compatibility;
-   bool is_desktop_gl = _mesa_is_desktop_gl(ctx);
-   this->Const.GLSL_110 = is_desktop_gl;
-   this->Const.GLSL_120 = is_desktop_gl && (ctx->Const.GLSLVersion >= 120);
-   this->Const.GLSL_130 = is_desktop_gl && (ctx->Const.GLSLVersion >= 130);
-   this->Const.GLSL_140 = is_desktop_gl && (ctx->Const.GLSLVersion >= 140);
-
    const unsigned lowest_version =
       (ctx->API == API_OPENGLES2) || ctx->Extensions.ARB_ES2_compatibility
       ? 100 : 110;
    const unsigned highest_version =
-      is_desktop_gl ? ctx->Const.GLSLVersion : 100;
+      _mesa_is_desktop_gl(ctx) ? ctx->Const.GLSLVersion : 100;
    char *supported = ralloc_strdup(this, "");
 
    for (unsigned ver = lowest_version; ver <= highest_version; ver += 10) {
@@ -119,6 +107,10 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
 
    if (ctx->Const.ForceGLSLExtensionsWarn)
       _mesa_glsl_process_extension("all", NULL, "warn", NULL, this);
+
+   this->default_uniform_qualifier = new(this) ast_type_qualifier();
+   this->default_uniform_qualifier->flags.q.shared = 1;
+   this->default_uniform_qualifier->flags.q.column_major = 1;
 }
 
 const char *
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index fc5d11cb9..c0a96c730 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -91,6 +91,13 @@ struct _mesa_glsl_parse_state {
    const char *version_string;
    enum _mesa_glsl_parser_targets target;
 
+   /**
+    * Default uniform layout qualifiers tracked during parsing.
+    * Currently affects uniform blocks and uniform buffer variables in
+    * those blocks.
+    */
+   class ast_type_qualifier *default_uniform_qualifier;
+
    /**
     * Printable list of GLSL versions supported by the current context
     *
@@ -122,23 +129,6 @@ struct _mesa_glsl_parse_state {
 
       /* ARB_draw_buffers */
       unsigned MaxDrawBuffers;
-
-      /**
-       * Set of GLSL versions supported by the current context
-       *
-       * Knowing that version X is supported doesn't mean that versions before
-       * X are also supported.  Version 1.00 is only supported in an ES2
-       * context or when GL_ARB_ES2_compatibility is supported.  In an OpenGL
-       * 3.0 "forward compatible" context, GLSL 1.10 and 1.20 are \b not
-       * supported.
-       */
-      /*@{*/
-      unsigned GLSL_100ES:1;
-      unsigned GLSL_110:1;
-      unsigned GLSL_120:1;
-      unsigned GLSL_130:1;
-      unsigned GLSL_140:1;
-      /*@}*/
    } Const;
 
    /**
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index d7ef5d4d2..1baa46c5d 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -328,10 +328,21 @@ private:
 	 this->uniforms[id].offset = this->ubo_byte_offset;
 	 this->ubo_byte_offset += type->std140_size(ubo_var->RowMajor);
 
-	 this->uniforms[id].array_stride = 0;
-	 this->uniforms[id].matrix_stride = 0;
-	 this->uniforms[id].row_major = base_type->is_matrix() &&
-	    ubo_var->RowMajor;
+	 if (type->is_array()) {
+	    this->uniforms[id].array_stride =
+	       align(type->fields.array->std140_size(ubo_var->RowMajor), 16);
+	 } else {
+	    this->uniforms[id].array_stride = 0;
+	 }
+
+	 if (type->is_matrix() ||
+	     (type->is_array() && type->fields.array->is_matrix())) {
+	    this->uniforms[id].matrix_stride = 16;
+	    this->uniforms[id].row_major = ubo_var->RowMajor;
+	 } else {
+	    this->uniforms[id].matrix_stride = 0;
+	    this->uniforms[id].row_major = false;
+	 }
       } else {
 	 this->uniforms[id].block_index = -1;
 	 this->uniforms[id].offset = -1;
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index bfdde4023..34ce13372 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -2324,6 +2324,12 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
       0          /* FINISHME: Geometry shaders. */
    };
 
+   const unsigned max_uniform_blocks[MESA_SHADER_TYPES] = {
+      ctx->Const.VertexProgram.MaxUniformBlocks,
+      ctx->Const.FragmentProgram.MaxUniformBlocks,
+      ctx->Const.GeometryProgram.MaxUniformBlocks,
+   };
+
    for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
       struct gl_shader *sh = prog->_LinkedShaders[i];
 
@@ -2348,6 +2354,34 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
       }
    }
 
+   unsigned blocks[MESA_SHADER_TYPES] = {0};
+   unsigned total_uniform_blocks = 0;
+
+   for (unsigned i = 0; i < prog->NumUniformBlocks; i++) {
+      for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) {
+	 if (prog->UniformBlockStageIndex[j][i] != -1) {
+	    blocks[j]++;
+	    total_uniform_blocks++;
+	 }
+      }
+
+      if (total_uniform_blocks > ctx->Const.MaxCombinedUniformBlocks) {
+	 linker_error(prog, "Too many combined uniform blocks (%d/%d)",
+		      prog->NumUniformBlocks,
+		      ctx->Const.MaxCombinedUniformBlocks);
+      } else {
+	 for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+	    if (blocks[i] > max_uniform_blocks[i]) {
+	       linker_error(prog, "Too many %s uniform blocks (%d/%d)",
+			    shader_names[i],
+			    blocks[i],
+			    max_uniform_blocks[i]);
+	       break;
+	    }
+	 }
+      }
+   }
+
    return prog->LinkStatus;
 }
 
-- 
cgit v1.2.3