From: Kenneth Graunke Date: Mon, 6 Dec 2010 18:54:21 +0000 (-0800) Subject: glsl: Properly add functions during lazy built-in prototype importing. X-Git-Tag: mesa-7.10~169 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c17c7903871b031162e41d6495a1bef64844e19b;p=platform%2Fupstream%2Fmesa.git glsl: Properly add functions during lazy built-in prototype importing. The original lazy built-in importing patch did not add the newly created function to the symbol table, nor actually emit it into the IR stream. Adding it to the symbol table is non-trivial since importing occurs when generating some ir_call in a nested scope. A new add_global_function method, backed by new symbol_table code in the previous patch, handles this. Fixes bug #32030. --- diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 1dd210a..6ecf779 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -99,23 +99,29 @@ match_function_by_name(exec_list *instructions, const char *name, { void *ctx = state; ir_function *f = state->symbols->get_function(name); - ir_function_signature *sig = NULL; + ir_function_signature *sig; + + sig = f ? f->matching_signature(actual_parameters) : NULL; /* FINISHME: This doesn't handle the case where shader X contains a * FINISHME: matching signature but shader X + N contains an _exact_ * FINISHME: matching signature. */ - if (f != NULL) { - sig = f->matching_signature(actual_parameters); - } else if (state->symbols->get_type(name) == NULL && (state->language_version == 110 || state->symbols->get_variable(name) == NULL)) { + if (sig == NULL && (f == NULL || state->es_shader || !f->has_user_signature()) && state->symbols->get_type(name) == NULL && (state->language_version == 110 || state->symbols->get_variable(name) == NULL)) { /* The current shader doesn't contain a matching function or signature. * Before giving up, look for the prototype in the built-in functions. */ for (unsigned i = 0; i < state->num_builtins_to_link; i++) { - f = state->builtins_to_link[i]->symbols->get_function(name); - sig = f ? f->matching_signature(actual_parameters) : NULL; + ir_function *builtin; + builtin = state->builtins_to_link[i]->symbols->get_function(name); + sig = builtin ? builtin->matching_signature(actual_parameters) : NULL; if (sig != NULL) { - f = new(ctx) ir_function(name); + if (f == NULL) { + f = new(ctx) ir_function(name); + state->symbols->add_global_function(f); + emit_function(state, instructions, f); + } + f->add_signature(sig->clone_prototype(f, NULL)); break; } diff --git a/src/glsl/glsl_symbol_table.cpp b/src/glsl/glsl_symbol_table.cpp index fb22a17..3dcd928 100644 --- a/src/glsl/glsl_symbol_table.cpp +++ b/src/glsl/glsl_symbol_table.cpp @@ -135,6 +135,13 @@ bool glsl_symbol_table::add_function(ir_function *f) return _mesa_symbol_table_add_symbol(table, -1, f->name, entry) == 0; } +void glsl_symbol_table::add_global_function(ir_function *f) +{ + symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); + int added = _mesa_symbol_table_add_global_symbol(table, -1, f->name, entry); + assert(added == 0); +} + ir_variable *glsl_symbol_table::get_variable(const char *name) { symbol_table_entry *entry = get_entry(name); diff --git a/src/glsl/glsl_symbol_table.h b/src/glsl/glsl_symbol_table.h index 329cd10..28a44eb 100644 --- a/src/glsl/glsl_symbol_table.h +++ b/src/glsl/glsl_symbol_table.h @@ -103,6 +103,11 @@ public: /*@}*/ /** + * Add an function at global scope without checking for scoping conflicts. + */ + void add_global_function(ir_function *f); + + /** * \name Methods to get symbols from the table */ /*@{*/