[Mesa-dev] [PATCH 6/9] glsl: parser UBO support

Vincent Lejeune vljn at ovi.com
Thu Dec 1 07:35:35 PST 2011


   v2:Instance name an UBO array are not supported. The parser
   will now return an error message if they are met.
---
 src/glsl/ast.h                  |   23 +++
 src/glsl/ast_to_hir.cpp         |   75 +++++++++-
 src/glsl/glsl_lexer.ll          |    3 +-
 src/glsl/glsl_parser.yy         |  333 +++++++++++++++++++++++++++++----------
 src/glsl/glsl_parser_extras.cpp |    5 +
 src/glsl/glsl_parser_extras.h   |    7 +
 src/mesa/program/ir_to_mesa.cpp |   12 ++-
 7 files changed, 369 insertions(+), 89 deletions(-)

diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index d899bc6..8effa5b 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -351,6 +351,15 @@ struct ast_type_qualifier {
 	  */
 	 unsigned explicit_location:1;
 
+         /** UBO Layout, should be 2 enum but using bit instead
+          *  to be coherent with struct definition
+          */
+         unsigned std140:1;
+         unsigned packed:1;
+         unsigned shared:1;
+         unsigned column_major:1;
+         unsigned row_major:1;
+
          /** \name Layout qualifiers for GL_AMD_conservative_depth */
          /** \{ */
          unsigned depth_any:1;
@@ -539,6 +548,20 @@ public:
    int invariant;
 };
 
+class ast_uniform_buffer_object : public ast_node {
+public:
+    ast_uniform_buffer_object(ast_declarator_list* lst,char* n) : name(n) {
+      components.push_degenerate_list_at_head(& lst->link);
+    }
+
+    virtual ir_rvalue *hir(exec_list *instructions,
+                           struct _mesa_glsl_parse_state *state);
+
+    exec_list components;
+    ast_type_qualifier layout_qualifier;
+    const char* name;
+};
+
 
 class ast_parameter_declarator : public ast_node {
 public:
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index d5b04e9..a76523a 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -81,6 +81,7 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
     * by the linker.
     */
    state->symbols->push_scope();
+   state->ubo_count = 0;
 
    foreach_list_typed (ast_node, ast, link, & state->translation_unit)
       ast->hir(instructions, state);
@@ -1967,8 +1968,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    else if (qual->flags.q.out
 	    || (qual->flags.q.varying && (state->target == vertex_shader)))
       var->mode = ir_var_out;
-   else if (qual->flags.q.uniform)
+   else if (qual->flags.q.uniform) {
       var->mode = ir_var_uniform;
+   }
 
    if (state->all_invariant && (state->current_function == NULL)) {
       switch (state->target) {
@@ -2915,6 +2917,77 @@ ast_declarator_list::hir(exec_list *instructions,
    return result;
 }
 
+ir_rvalue *
+ast_uniform_buffer_object::hir(exec_list *instructions, _mesa_glsl_parse_state *state)
+{
+   void *ctx = state;
+   YYLTYPE loc = this->get_location();
+
+#if FEATURE_ARB_uniform_buffer_object
+
+   /**
+     * Counting variable the hard way.
+     */
+   int var_count = 0;
+   foreach_list_typed (ast_declarator_list, decl_list, link,
+                       &this->components) {
+      decl_list->hir(instructions,state);
+
+      foreach_list_typed (ast_declaration, decl, link,
+                          &decl_list->declarations) {
+         var_count++;
+      }
+   }
+
+   if(state->ubo_count == 0)
+      state->UniformBufferObjects = (struct gl_uniform_buffer_object*)
+            ralloc_array_size(ctx, sizeof(gl_uniform_buffer_object),1);
+   else
+      state->UniformBufferObjects =  (struct gl_uniform_buffer_object*)
+            reralloc_array_size(ctx, state->UniformBufferObjects, sizeof(gl_uniform_buffer_object), state->ubo_count + 1);
+
+   gl_uniform_buffer_object& new_ubo = state->UniformBufferObjects[state->ubo_count];
+
+   state->ubo_count++;
+
+   void* inner_ctx = (void*) state->UniformBufferObjects;
+   new_ubo.NumberOfVariables = var_count;
+   new_ubo.StorageLayout.Compact = (struct gl_shader_ubo_variable*) ralloc_array_size(inner_ctx,sizeof(gl_shader_ubo_variable),var_count);
+   new_ubo.Name = ralloc_strdup(inner_ctx,this->name);
+
+   int var_position = 0;
+   foreach_list_typed (ast_declarator_list, decl_list, link,
+                       &this->components) {
+      foreach_list_typed (ast_declaration, decl, link,
+                          &decl_list->declarations) {
+         struct gl_shader_ubo_variable& var_ubo = new_ubo.StorageLayout.Compact[var_position];
+         var_ubo.Name = ralloc_strdup(inner_ctx,decl->identifier);
+
+         ir_variable* var = state->symbols->get_variable(var_ubo.Name);
+         var->mode = ir_var_uniform;
+         var->is_ubo_variable = true;
+         var_ubo.Type = var->type;
+
+         var_position++;
+      }
+   }
+
+   if(this->layout_qualifier.flags.q.std140)
+      new_ubo.Layout = UBO_LAYOUT_SDT140;
+   if(this->layout_qualifier.flags.q.packed)
+      new_ubo.Layout = UBO_LAYOUT_PACKED;
+   if(this->layout_qualifier.flags.q.shared)
+      new_ubo.Layout = UBO_LAYOUT_SHARED;
+   if(this->layout_qualifier.flags.q.column_major)
+      new_ubo.Layout = UBO_MATRIX_LAYOUT_COLUMN_MAJOR;
+   if(this->layout_qualifier.flags.q.row_major)
+      new_ubo.Layout = UBO_MATRIX_LAYOUT_ROW_MAJOR;
+
+#endif
+
+   return NULL;
+}
+
 
 ir_rvalue *
 ast_parameter_declarator::hir(exec_list *instructions,
diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll
index c7cfedd..c5d0ec4 100644
--- a/src/glsl/glsl_lexer.ll
+++ b/src/glsl/glsl_lexer.ll
@@ -312,7 +312,8 @@ layout		{
 		      || yyextra->AMD_conservative_depth_enable
 		      || yyextra->ARB_conservative_depth_enable
 		      || yyextra->ARB_explicit_attrib_location_enable
-		      || yyextra->ARB_fragment_coord_conventions_enable) {
+		      || yyextra->ARB_fragment_coord_conventions_enable
+		      || yyextra->ARB_uniform_buffer_object_enable) {
 		      return LAYOUT_TOK;
 		   } else {
 		      yylval->identifier = strdup(yytext);
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 71ab039..f4d00ec 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -72,15 +72,16 @@
    ast_case_label_list *case_label_list;
    ast_case_statement *case_statement;
    ast_case_statement_list *case_statement_list;
+   ast_uniform_buffer_object *uniform_buffer_object;
 
    struct {
-      ast_node *cond;
-      ast_expression *rest;
+ast_node *cond;
+ast_expression *rest;
    } for_rest_statement;
 
    struct {
-      ast_node *then_statement;
-      ast_node *else_statement;
+ast_node *then_statement;
+ast_node *else_statement;
    } selection_rest_statement;
 }
 
@@ -142,6 +143,7 @@
 %type <node> statement_list
 %type <node> simple_statement
 %type <n> precision_qualifier
+%type <node> layout_defaults
 %type <type_qualifier> type_qualifier
 %type <type_qualifier> storage_qualifier
 %type <type_qualifier> interpolation_qualifier
@@ -201,6 +203,11 @@
 %type <node> external_declaration
 %type <declarator_list> init_declarator_list
 %type <declarator_list> single_declaration
+%type <uniform_buffer_object> uniform_buffer_object
+%type <uniform_buffer_object> uniform_buffer_object_block
+%type <declarator_list> uniform_buffer_object_declaration_list
+%type <declarator_list> ubo_variables_declarator_list
+%type <declarator_list> ubo_single_declaration
 %type <expression> initializer
 %type <node> declaration
 %type <node> declaration_statement
@@ -246,35 +253,35 @@ version_statement:
 
 	   switch ($2) {
 	   case 100:
-	      state->es_shader = true;
-	      supported = state->Const.GLSL_100ES;
-	      break;
+	state->es_shader = true;
+	supported = state->Const.GLSL_100ES;
+	break;
 	   case 110:
-	      supported = state->Const.GLSL_110;
-	      break;
+	supported = state->Const.GLSL_110;
+	break;
 	   case 120:
-	      supported = state->Const.GLSL_120;
-	      break;
+	supported = state->Const.GLSL_120;
+	break;
 	   case 130:
-	      supported = state->Const.GLSL_130;
-	      break;
+	supported = state->Const.GLSL_130;
+	break;
 	   default:
-	      supported = false;
-	      break;
+	supported = false;
+	break;
 	   }
 
 	   state->language_version = $2;
 	   state->version_string =
-	      ralloc_asprintf(state, "GLSL%s %d.%02d",
-			      state->es_shader ? " ES" : "",
-			      state->language_version / 100,
-			      state->language_version % 100);
+	ralloc_asprintf(state, "GLSL%s %d.%02d",
+			state->es_shader ? " ES" : "",
+			state->language_version / 100,
+			state->language_version % 100);
 
 	   if (!supported) {
-	      _mesa_glsl_error(& @2, state, "%s is not supported. "
-			       "Supported versions are: %s\n",
-			       state->version_string,
-			       state->supported_version_string);
+	_mesa_glsl_error(& @2, state, "%s is not supported. "
+			 "Supported versions are: %s\n",
+			 state->version_string,
+			 state->supported_version_string);
 	   }
 	}
 	;
@@ -287,11 +294,11 @@ pragma_statement:
 	| PRAGMA_INVARIANT_ALL EOL
 	{
 	   if (state->language_version < 120) {
-	      _mesa_glsl_warning(& @1, state,
+	_mesa_glsl_warning(& @1, state,
 				 "pragma `invariant(all)' not supported in %s",
 				 state->version_string);
 	   } else {
-	      state->all_invariant = true;
+	state->all_invariant = true;
 	   }
 	}
 	;
@@ -311,7 +318,7 @@ extension_statement:
 	EXTENSION any_identifier COLON any_identifier EOL
 	{
 	   if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) {
-	      YYERROR;
+	YYERROR;
 	   }
 	}
 	;
@@ -323,7 +330,7 @@ external_declaration_list:
 	    * FINISHME: NULL. (See production rule for external_declaration.)
 	    */
 	   if ($1 != NULL)
-	      state->translation_unit.push_tail(& $1->link);
+	state->translation_unit.push_tail(& $1->link);
 	}
 	| external_declaration_list external_declaration
 	{
@@ -331,7 +338,7 @@ external_declaration_list:
 	    * FINISHME: NULL. (See production rule for external_declaration.)
 	    */
 	   if ($2 != NULL)
-	      state->translation_unit.push_tail(& $2->link);
+	state->translation_unit.push_tail(& $2->link);
 	}
 	;
 
@@ -758,11 +765,11 @@ expression:
 	{
 	   void *ctx = state;
 	   if ($1->oper != ast_sequence) {
-	      $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL);
-	      $$->set_location(yylloc);
-	      $$->expressions.push_tail(& $1->link);
+	$$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL);
+	$$->set_location(yylloc);
+	$$->expressions.push_tail(& $1->link);
 	   } else {
-	      $$ = $1;
+	$$ = $1;
 	   }
 
 	   $$->expressions.push_tail(& $3->link);
@@ -789,6 +796,11 @@ declaration:
 	   $3->is_precision_statement = true;
 	   $$ = $3;
 	}
+   | uniform_buffer_object ';'
+   {
+$$ = $1;
+   }
+   | layout_defaults { $$ = NULL;}
 	;
 
 function_prototype:
@@ -1054,6 +1066,126 @@ single_declaration:
 	}
 	;
 
+
+
+uniform_buffer_object:
+   uniform_buffer_object_block
+   {
+      $1->layout_qualifier = *(state->default_layout);
+      $$ = $1;
+   }
+   | layout_qualifier uniform_buffer_object_block
+   {
+      $2->layout_qualifier = $1;
+      $$ = $2;
+   }
+   ;
+
+// IDENTIFIER is more accurate than any_identifier, resulting in absence of shift/reduce conflict
+uniform_buffer_object_block:
+   UNIFORM NEW_IDENTIFIER '{' uniform_buffer_object_declaration_list '}'
+   {
+      void *ctx = state;
+      ast_uniform_buffer_object *ubo = new (ctx) ast_uniform_buffer_object($4,$2);
+      $$ = ubo;
+   }
+   | UNIFORM NEW_IDENTIFIER '{' uniform_buffer_object_declaration_list '}' NEW_IDENTIFIER
+   {
+      _mesa_glsl_error(& @1, state, "Instance name not supported");
+   }
+   | UNIFORM NEW_IDENTIFIER '{' uniform_buffer_object_declaration_list '}' NEW_IDENTIFIER '[' expression ']'
+   {
+      _mesa_glsl_error(& @1, state, "Array of UBO not supported");
+   }
+   ;
+
+
+uniform_buffer_object_declaration_list:
+   ubo_variables_declarator_list ';'
+   {
+      $$ = $1;
+      $1->link.self_link();
+   }
+   | uniform_buffer_object_declaration_list ubo_variables_declarator_list ';'
+   {
+      $$ = $1;
+      $$->link.insert_before(& $2->link);
+   }
+   ;
+
+// No initializer here...
+ubo_variables_declarator_list:
+   ubo_single_declaration
+   | ubo_variables_declarator_list ',' any_identifier
+   {
+      void *ctx = state;
+      ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL);
+      decl->set_location(yylloc);
+
+      $$ = $1;
+      $$->declarations.push_tail(&decl->link);
+      state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+   }
+   | ubo_variables_declarator_list ',' any_identifier '[' ']'
+   {
+      void *ctx = state;
+      ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL);
+      decl->set_location(yylloc);
+
+      $$ = $1;
+      $$->declarations.push_tail(&decl->link);
+      state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+   }
+   | ubo_variables_declarator_list ',' any_identifier '[' constant_expression ']'
+   {
+      void *ctx = state;
+      ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL);
+      decl->set_location(yylloc);
+
+      $$ = $1;
+      $$->declarations.push_tail(&decl->link);
+      state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+   }
+   ;
+
+// No initializer here
+ubo_single_declaration:
+   fully_specified_type
+   {
+      void *ctx = state;
+      /* Empty declaration list is valid. */
+      $$ = new(ctx) ast_declarator_list($1);
+      $$->set_location(yylloc);
+   }
+   | fully_specified_type any_identifier
+   {
+      void *ctx = state;
+      ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL);
+
+      $$ = new(ctx) ast_declarator_list($1);
+      $$->set_location(yylloc);
+      $$->declarations.push_tail(&decl->link);
+   }
+   | fully_specified_type any_identifier '[' ']'
+   {
+      void *ctx = state;
+      ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL);
+
+      $$ = new(ctx) ast_declarator_list($1);
+      $$->set_location(yylloc);
+      $$->declarations.push_tail(&decl->link);
+   }
+   | fully_specified_type any_identifier '[' constant_expression ']'
+   {
+      void *ctx = state;
+      ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL);
+
+      $$ = new(ctx) ast_declarator_list($1);
+      $$->set_location(yylloc);
+      $$->declarations.push_tail(&decl->link);
+   }
+   ;
+
 fully_specified_type:
 	type_specifier
 	{
@@ -1084,18 +1216,18 @@ layout_qualifier_id_list:
 	| 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");
-	      YYERROR;
+	_mesa_glsl_error(& @3, state,
+			 "duplicate layout qualifiers used\n");
+	YYERROR;
 	   }
 
 	   $$.flags.i = $1.flags.i | $3.flags.i;
 
 	   if ($1.flags.q.explicit_location)
-	      $$.location = $1.location;
+	$$.location = $1.location;
 
 	   if ($3.flags.q.explicit_location)
-	      $$.location = $3.location;
+	$$.location = $3.location;
 	}
 	;
 
@@ -1108,55 +1240,79 @@ layout_qualifier_id:
 
 	   /* Layout qualifiers for ARB_fragment_coord_conventions. */
 	   if (!got_one && state->ARB_fragment_coord_conventions_enable) {
-	      if (strcmp($1, "origin_upper_left") == 0) {
+	if (strcmp($1, "origin_upper_left") == 0) {
 		 got_one = true;
 		 $$.flags.q.origin_upper_left = 1;
-	      } else if (strcmp($1, "pixel_center_integer") == 0) {
+	} else if (strcmp($1, "pixel_center_integer") == 0) {
 		 got_one = true;
 		 $$.flags.q.pixel_center_integer = 1;
-	      }
+	}
 
-	      if (got_one && state->ARB_fragment_coord_conventions_warn) {
+	if (got_one && state->ARB_fragment_coord_conventions_warn) {
 		 _mesa_glsl_warning(& @1, state,
 				    "GL_ARB_fragment_coord_conventions layout "
 				    "identifier `%s' used\n", $1);
-	      }
+	}
 	   }
 
 	   /* Layout qualifiers for AMD/ARB_conservative_depth. */
 	   if (!got_one &&
-	       (state->AMD_conservative_depth_enable ||
-	        state->ARB_conservative_depth_enable)) {
-	      if (strcmp($1, "depth_any") == 0) {
-	         got_one = true;
-	         $$.flags.q.depth_any = 1;
-	      } else if (strcmp($1, "depth_greater") == 0) {
-	         got_one = true;
-	         $$.flags.q.depth_greater = 1;
-	      } else if (strcmp($1, "depth_less") == 0) {
-	         got_one = true;
-	         $$.flags.q.depth_less = 1;
-	      } else if (strcmp($1, "depth_unchanged") == 0) {
-	         got_one = true;
-	         $$.flags.q.depth_unchanged = 1;
-	      }
+	 (state->AMD_conservative_depth_enable ||
+	  state->ARB_conservative_depth_enable)) {
+	if (strcmp($1, "depth_any") == 0) {
+	   got_one = true;
+	   $$.flags.q.depth_any = 1;
+	} else if (strcmp($1, "depth_greater") == 0) {
+	   got_one = true;
+	   $$.flags.q.depth_greater = 1;
+	} else if (strcmp($1, "depth_less") == 0) {
+	   got_one = true;
+	   $$.flags.q.depth_less = 1;
+	} else if (strcmp($1, "depth_unchanged") == 0) {
+	   got_one = true;
+	   $$.flags.q.depth_unchanged = 1;
+	}
 	
-	      if (got_one && state->AMD_conservative_depth_warn) {
-	         _mesa_glsl_warning(& @1, state,
-	                            "GL_AMD_conservative_depth "
-	                            "layout qualifier `%s' is used\n", $1);
-	      }
-	      if (got_one && state->ARB_conservative_depth_warn) {
-	         _mesa_glsl_warning(& @1, state,
-	                            "GL_ARB_conservative_depth "
-	                            "layout qualifier `%s' is used\n", $1);
-	      }
+	if (got_one && state->AMD_conservative_depth_warn) {
+	   _mesa_glsl_warning(& @1, state,
+	    "GL_AMD_conservative_depth "
+	    "layout qualifier `%s' is used\n", $1);
+	}
+	if (got_one && state->ARB_conservative_depth_warn) {
+	   _mesa_glsl_warning(& @1, state,
+	    "GL_ARB_conservative_depth "
+	    "layout qualifier `%s' is used\n", $1);
+	}
 	   }
 
+     /* Layout qualifiers for UBO */
+     if (!got_one) {
+  if (strcmp($1, "std140") == 0) {
+    got_one = true;
+    $$.flags.q.std140 = 1;
+  }
+  else if (strcmp($1, "packed") == 0) {
+    got_one = true;
+    $$.flags.q.packed = 1;
+  }
+  else if (strcmp($1, "shared") == 0) {
+    got_one = true;
+    $$.flags.q.shared = 1;
+  }
+  else if (strcmp($1, "column_major") == 0) {
+    got_one = true;
+    $$.flags.q.column_major = 1;
+  }
+  else if (strcmp($1, "row_major") == 0) {
+    got_one = true;
+    $$.flags.q.row_major = 1;
+  }
+}
+
 	   if (!got_one) {
-	      _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
-			       "`%s'\n", $1);
-	      YYERROR;
+	_mesa_glsl_error(& @1, state, "unrecognized layout identifier "
+			 "`%s'\n", $1);
+	YYERROR;
 	   }
 	}
 	| any_identifier '=' INTCONSTANT
@@ -1166,10 +1322,10 @@ layout_qualifier_id:
 	   memset(& $$, 0, sizeof($$));
 
 	   if (state->ARB_explicit_attrib_location_enable) {
-	      /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and
-	       * FINISHME: GLSL 1.30 (or later) are supported.
-	       */
-	      if (strcmp("location", $1) == 0) {
+	/* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and
+	 * FINISHME: GLSL 1.30 (or later) are supported.
+	 */
+	if (strcmp("location", $1) == 0) {
 		 got_one = true;
 
 		 $$.flags.q.explicit_location = 1;
@@ -1181,18 +1337,18 @@ layout_qualifier_id:
 				     "invalid location %d specified\n", $3);
 		    YYERROR;
 		 }
-	      }
+	}
 	   }
 
 	   /* If the identifier didn't match any known layout identifiers,
 	    * emit an error.
 	    */
 	   if (!got_one) {
-	      _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
-			       "`%s'\n", $1);
-	      YYERROR;
+	_mesa_glsl_error(& @1, state, "unrecognized layout identifier "
+			 "`%s'\n", $1);
+	YYERROR;
 	   } else if (state->ARB_explicit_attrib_location_warn) {
-	      _mesa_glsl_warning(& @1, state,
+	_mesa_glsl_warning(& @1, state,
 				 "GL_ARB_explicit_attrib_location layout "
 				 "identifier `%s' used\n", $1);
 	   }
@@ -1414,7 +1570,7 @@ precision_qualifier:
 	HIGHP	  {
 		     if (!state->es_shader && state->language_version < 130)
 			_mesa_glsl_error(& @1, state,
-				         "precision qualifier forbidden "
+				   "precision qualifier forbidden "
 					 "in %s (1.30 or later "
 					 "required)\n",
 					 state->version_string);
@@ -1531,13 +1687,20 @@ statement:
 	| simple_statement
 	;
 
+layout_defaults:
+layout_qualifier UNIFORM ';'
+{
+   *(state->default_layout) = $1;
+}
+;
+
 simple_statement:
 	declaration_statement
 	| expression_statement
 	| selection_statement
 	| switch_statement
 	| iteration_statement
-	| jump_statement
+| jump_statement
 	;
 
 compound_statement:
@@ -1584,8 +1747,8 @@ statement_list:
 	statement
 	{
 	   if ($1 == NULL) {
-	      _mesa_glsl_error(& @1, state, "<nil> statement\n");
-	      assert($1 != NULL);
+	_mesa_glsl_error(& @1, state, "<nil> statement\n");
+	assert($1 != NULL);
 	   }
 
 	   $$ = $1;
@@ -1594,8 +1757,8 @@ statement_list:
 	| statement_list statement
 	{
 	   if ($2 == NULL) {
-	      _mesa_glsl_error(& @2, state, "<nil> statement\n");
-	      assert($2 != NULL);
+	_mesa_glsl_error(& @2, state, "<nil> statement\n");
+	assert($2 != NULL);
 	   }
 	   $$ = $1;
 	   $$->link.insert_before(& $2->link);
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index 71b4c5c..6b7eee2 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -36,6 +36,8 @@ extern "C" {
 #include "ir_optimization.h"
 #include "loop_analysis.h"
 
+static ast_type_qualifier layout_container[1];
+
 _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx,
 					       GLenum target, void *mem_ctx)
 {
@@ -114,6 +116,9 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx,
    }
 
    this->supported_version_string = supported;
+   this->default_layout = layout_container;
+   default_layout->flags.q.column_major = 1;
+   default_layout->flags.q.shared = 1;
 }
 
 const char *
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 572e614..8eb2ffc 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -42,6 +42,9 @@ enum _mesa_glsl_parser_targets {
 
 struct gl_context;
 
+#include <main/mtypes.h>
+
+
 struct _mesa_glsl_parse_state {
    _mesa_glsl_parse_state(struct gl_context *ctx, GLenum target,
 			  void *mem_ctx);
@@ -204,6 +207,10 @@ struct _mesa_glsl_parse_state {
    /** Shaders containing built-in functions that are used for linking. */
    struct gl_shader *builtins_to_link[16];
    unsigned num_builtins_to_link;
+
+   struct gl_uniform_buffer_object* UniformBufferObjects;
+   unsigned ubo_count;
+   struct ast_type_qualifier * default_layout;
 };
 
 typedef struct YYLTYPE {
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 5a68fc5..3fde781 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2617,7 +2617,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
       ir_variable *var = ((ir_instruction *) node)->as_variable();
 
       if ((var == NULL) || (var->mode != ir_var_uniform)
-	  || (strncmp(var->name, "gl_", 3) == 0))
+        || (strncmp(var->name, "gl_", 3) == 0) || var->is_ubo_variable)
 	 continue;
 
       add.process(var);
@@ -2693,6 +2693,8 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
 	 last_location = location;
       }
    }
+
+   params->NumUBO = shader_program->UBOCount;
 }
 
 static void
@@ -3327,7 +3329,6 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
    return prog->LinkStatus;
 }
 
-
 /**
  * Compile a GLSL shader.  Called via glCompileShader().
  */
@@ -3387,6 +3388,13 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader)
 	  sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
    shader->num_builtins_to_link = state->num_builtins_to_link;
 
+
+#if FEATURE_ARB_uniform_buffer_object
+   shader->UBOCount = state->ubo_count;
+   shader->UniformBufferObjects = state->UniformBufferObjects;
+   ralloc_steal(shader,shader->UniformBufferObjects);
+#endif
+
    if (ctx->Shader.Flags & GLSL_LOG) {
       _mesa_write_shader_to_file(shader);
    }
-- 
1.7.7



More information about the mesa-dev mailing list