From f5692f452f7ae77d1e710041ffebb468cc5ba87b Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 11 Nov 2010 12:11:27 -0800 Subject: [PATCH] glsl: Lazily import built-in function prototypes. This makes a very simple 1.30 shader go from 196k of memory to 9k. NOTE: This -may- be a candidate for the 7.9 branch, as the benefit is substantial. However, it's not a simple change, so it may be wiser to wait for 7.10. --- src/glsl/ast_function.cpp | 69 ++++++++++++-------- src/glsl/builtin_function.cpp | 1 - src/glsl/builtins/tools/generate_builtins.py | 1 - 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 1e66033348c..1dd210a6797 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -93,13 +93,34 @@ prototype_string(const glsl_type *return_type, const char *name, static ir_rvalue * -process_call(exec_list *instructions, ir_function *f, - YYLTYPE *loc, exec_list *actual_parameters, - struct _mesa_glsl_parse_state *state) +match_function_by_name(exec_list *instructions, const char *name, + YYLTYPE *loc, exec_list *actual_parameters, + struct _mesa_glsl_parse_state *state) { void *ctx = state; + ir_function *f = state->symbols->get_function(name); + ir_function_signature *sig = NULL; - ir_function_signature *sig = f->matching_signature(actual_parameters); + /* 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)) { + /* 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; + if (sig != NULL) { + f = new(ctx) ir_function(name); + f->add_signature(sig->clone_prototype(f, NULL)); + break; + } + } + } if (sig != NULL) { /* Verify that 'out' and 'inout' actual parameters are lvalues. This @@ -164,45 +185,35 @@ process_call(exec_list *instructions, ir_function *f, return NULL; } } else { - char *str = prototype_string(NULL, f->name, actual_parameters); + char *str = prototype_string(NULL, name, actual_parameters); _mesa_glsl_error(loc, state, "no matching function for call to `%s'", str); talloc_free(str); const char *prefix = "candidates are: "; - foreach_list (node, &f->signatures) { - ir_function_signature *sig = (ir_function_signature *) node; - str = prototype_string(sig->return_type, f->name, &sig->parameters); - _mesa_glsl_error(loc, state, "%s%s\n", prefix, str); - talloc_free(str); + for (int i = -1; i < state->num_builtins_to_link; i++) { + glsl_symbol_table *syms = i >= 0 ? state->builtins_to_link[i]->symbols + : state->symbols; + f = syms->get_function(name); + if (f == NULL) + continue; - prefix = " "; - } + foreach_list (node, &f->signatures) { + ir_function_signature *sig = (ir_function_signature *) node; - return ir_call::get_error_instruction(ctx); - } -} + str = prototype_string(sig->return_type, f->name, &sig->parameters); + _mesa_glsl_error(loc, state, "%s%s\n", prefix, str); + talloc_free(str); + prefix = " "; + } -static ir_rvalue * -match_function_by_name(exec_list *instructions, const char *name, - YYLTYPE *loc, exec_list *actual_parameters, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - ir_function *f = state->symbols->get_function(name); + } - if (f == NULL) { - _mesa_glsl_error(loc, state, "function `%s' undeclared", name); return ir_call::get_error_instruction(ctx); } - - /* Once we've determined that the function being called might exist, try - * to find an overload of the function that matches the parameters. - */ - return process_call(instructions, f, loc, actual_parameters, state); } diff --git a/src/glsl/builtin_function.cpp b/src/glsl/builtin_function.cpp index bc368141053..631aeac12ce 100644 --- a/src/glsl/builtin_function.cpp +++ b/src/glsl/builtin_function.cpp @@ -13590,7 +13590,6 @@ _mesa_read_profile(struct _mesa_glsl_parse_state *state, builtin_profiles[profile_index] = sh; } - import_prototypes(sh->ir, instructions, state->symbols, state); state->builtins_to_link[state->num_builtins_to_link] = sh; state->num_builtins_to_link++; } diff --git a/src/glsl/builtins/tools/generate_builtins.py b/src/glsl/builtins/tools/generate_builtins.py index 1f1056ea096..5ea4b5c48f4 100755 --- a/src/glsl/builtins/tools/generate_builtins.py +++ b/src/glsl/builtins/tools/generate_builtins.py @@ -214,7 +214,6 @@ _mesa_read_profile(struct _mesa_glsl_parse_state *state, builtin_profiles[profile_index] = sh; } - import_prototypes(sh->ir, instructions, state->symbols, state); state->builtins_to_link[state->num_builtins_to_link] = sh; state->num_builtins_to_link++; } -- 2.30.2