mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 15:50:11 +01:00
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.
This commit is contained in:
parent
01a25bb64e
commit
f5692f452f
3 changed files with 42 additions and 33 deletions
|
|
@ -93,13 +93,34 @@ prototype_string(const glsl_type *return_type, const char *name,
|
||||||
|
|
||||||
|
|
||||||
static ir_rvalue *
|
static ir_rvalue *
|
||||||
process_call(exec_list *instructions, ir_function *f,
|
match_function_by_name(exec_list *instructions, const char *name,
|
||||||
YYLTYPE *loc, exec_list *actual_parameters,
|
YYLTYPE *loc, exec_list *actual_parameters,
|
||||||
struct _mesa_glsl_parse_state *state)
|
struct _mesa_glsl_parse_state *state)
|
||||||
{
|
{
|
||||||
void *ctx = 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) {
|
if (sig != NULL) {
|
||||||
/* Verify that 'out' and 'inout' actual parameters are lvalues. This
|
/* Verify that 'out' and 'inout' actual parameters are lvalues. This
|
||||||
|
|
@ -164,13 +185,21 @@ process_call(exec_list *instructions, ir_function *f,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} 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'",
|
_mesa_glsl_error(loc, state, "no matching function for call to `%s'",
|
||||||
str);
|
str);
|
||||||
talloc_free(str);
|
talloc_free(str);
|
||||||
|
|
||||||
const char *prefix = "candidates are: ";
|
const char *prefix = "candidates are: ";
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
foreach_list (node, &f->signatures) {
|
foreach_list (node, &f->signatures) {
|
||||||
ir_function_signature *sig = (ir_function_signature *) node;
|
ir_function_signature *sig = (ir_function_signature *) node;
|
||||||
|
|
||||||
|
|
@ -181,28 +210,10 @@ process_call(exec_list *instructions, ir_function *f,
|
||||||
prefix = " ";
|
prefix = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
return ir_call::get_error_instruction(ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
return ir_call::get_error_instruction(ctx);
|
||||||
* to find an overload of the function that matches the parameters.
|
}
|
||||||
*/
|
|
||||||
return process_call(instructions, f, loc, actual_parameters, state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13590,7 +13590,6 @@ _mesa_read_profile(struct _mesa_glsl_parse_state *state,
|
||||||
builtin_profiles[profile_index] = sh;
|
builtin_profiles[profile_index] = sh;
|
||||||
}
|
}
|
||||||
|
|
||||||
import_prototypes(sh->ir, instructions, state->symbols, state);
|
|
||||||
state->builtins_to_link[state->num_builtins_to_link] = sh;
|
state->builtins_to_link[state->num_builtins_to_link] = sh;
|
||||||
state->num_builtins_to_link++;
|
state->num_builtins_to_link++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,6 @@ _mesa_read_profile(struct _mesa_glsl_parse_state *state,
|
||||||
builtin_profiles[profile_index] = sh;
|
builtin_profiles[profile_index] = sh;
|
||||||
}
|
}
|
||||||
|
|
||||||
import_prototypes(sh->ir, instructions, state->symbols, state);
|
|
||||||
state->builtins_to_link[state->num_builtins_to_link] = sh;
|
state->builtins_to_link[state->num_builtins_to_link] = sh;
|
||||||
state->num_builtins_to_link++;
|
state->num_builtins_to_link++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue