glsl: Track UBO block names in the symbol table.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 28 Nov 2012 08:18:02 +0000 (00:18 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Sat, 19 Jan 2013 01:35:32 +0000 (17:35 -0800)
The GLSL 1.40 spec says:

    "Uniform block names and variable names declared within uniform
    blocks are scoped at the program level."

Track the block name in the symbol table and emit errors when conflicts
exist.

Fixes es3conform's uniform_buffer_object_block_name_conflict test, and
fixes the piglit block-name-clashes-with-{variable,function,struct}.vert
tests.

NOTE: This is a candidate for the 9.0 branch.

v2: Fix bad constructor initialization.  Noticed by Topi Pohjolainen.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/ast_to_hir.cpp
src/glsl/glsl_symbol_table.cpp
src/glsl/glsl_symbol_table.h

index ea5e3b773e380049ab01fa6c7733b0c0dbc09561..31dd51aa9216031960a65846acc9ea18fcca66c1 100644 (file)
@@ -4132,6 +4132,12 @@ ast_uniform_block::hir(exec_list *instructions,
    struct gl_uniform_block *ubo = get_next_uniform_block(state);
    ubo->Name = ralloc_strdup(state->uniform_blocks, this->block_name);
 
+   if (!state->symbols->add_uniform_block(ubo)) {
+      YYLTYPE loc = this->get_location();
+      _mesa_glsl_error(&loc, state, "Uniform block name `%s' already taken in "
+                       "the current scope.\n", ubo->Name);
+   }
+
    unsigned int num_variables = 0;
    foreach_list_typed(ast_declarator_list, decl_list, link, &declarations) {
       foreach_list_const(node, &decl_list->declarations) {
index f934ea8657063a5175d0ef6a367fcfff03b89c4d..eb275b12e293483a31d23ce49969db177033a78e 100644 (file)
@@ -41,13 +41,15 @@ public:
       ralloc_free(entry);
    }
 
-   symbol_table_entry(ir_variable *v)                     : v(v), f(0), t(0) {}
-   symbol_table_entry(ir_function *f)                     : v(0), f(f), t(0) {}
-   symbol_table_entry(const glsl_type *t)                 : v(0), f(0), t(t) {}
+   symbol_table_entry(ir_variable *v)               : v(v), f(0), t(0), u(0) {}
+   symbol_table_entry(ir_function *f)               : v(0), f(f), t(0), u(0) {}
+   symbol_table_entry(const glsl_type *t)           : v(0), f(0), t(t), u(0) {}
+   symbol_table_entry(struct gl_uniform_block *u)   : v(0), f(0), t(0), u(u) {}
 
    ir_variable *v;
    ir_function *f;
    const glsl_type *t;
+   struct gl_uniform_block *u;
 };
 
 glsl_symbol_table::glsl_symbol_table()
@@ -132,6 +134,12 @@ bool glsl_symbol_table::add_function(ir_function *f)
    return _mesa_symbol_table_add_symbol(table, -1, f->name, entry) == 0;
 }
 
+bool glsl_symbol_table::add_uniform_block(struct gl_uniform_block *u)
+{
+   symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(u);
+   return _mesa_symbol_table_add_symbol(table, -1, u->Name, entry) == 0;
+}
+
 void glsl_symbol_table::add_global_function(ir_function *f)
 {
    symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f);
index 9f5602787f083c1a077b8bb93d18debb28ebbe18..f95fb8a0115ac84c85343110105496fab007300a 100644 (file)
@@ -99,6 +99,7 @@ public:
    bool add_variable(ir_variable *v);
    bool add_type(const char *name, const glsl_type *t);
    bool add_function(ir_function *f);
+   bool add_uniform_block(struct gl_uniform_block *u);
    /*@}*/
 
    /**