mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
glsl: Emit function signatures at toplevel, even for built-ins.
The ast-to-hir conversion needs to emit function signatures in two circumstances: when a function declaration (or definition) is encountered, and when a built-in function is encountered. To avoid emitting a function signature in an illegal place (such as inside a function), emit_function() checked whether we were inside a function definition, and if so, emitted the signature before the function definition. However, this didn't cover the case of emitting function signatures for built-in functions when those built-in functions are called from inside the constant integer expression that specifies the length of a global array. This failed because when processing an array length, we are emitting IR into a dummy exec_list (see process_array_type() in ast_to_hir.cpp). process_array_type() later checks (via an assertion) that no instructions were emitted to the dummy exec_list, based on the reasonable assumption that we shouldn't need to emit instructions to calculate the value of a constant. This patch changes emit_function() so that it emits function signatures at toplevel in all cases. This partially fixes bug 38625 (https://bugs.freedesktop.org/show_bug.cgi?id=38625). The remainder of the fix is in the patch that follows. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
482338842d
commit
0d81b0e184
4 changed files with 22 additions and 20 deletions
|
|
@ -730,7 +730,6 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
|
|||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
void
|
||||
emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
|
||||
ir_function *f);
|
||||
emit_function(_mesa_glsl_parse_state *state, ir_function *f);
|
||||
|
||||
#endif /* AST_H */
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ match_function_by_name(exec_list *instructions, const char *name,
|
|||
if (f == NULL) {
|
||||
f = new(ctx) ir_function(name);
|
||||
state->symbols->add_global_function(f);
|
||||
emit_function(state, instructions, f);
|
||||
emit_function(state, f);
|
||||
}
|
||||
|
||||
f->add_signature(sig->clone_prototype(f, NULL));
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
|
|||
|
||||
state->current_function = NULL;
|
||||
|
||||
state->toplevel_ir = instructions;
|
||||
|
||||
/* Section 4.2 of the GLSL 1.20 specification states:
|
||||
* "The built-in functions are scoped in a scope outside the global scope
|
||||
* users declare global variables in. That is, a shader's global scope,
|
||||
|
|
@ -85,6 +87,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
|
|||
ast->hir(instructions, state);
|
||||
|
||||
detect_recursion_unlinked(state, instructions);
|
||||
|
||||
state->toplevel_ir = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2926,23 +2930,16 @@ ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
|
|||
|
||||
|
||||
void
|
||||
emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
|
||||
ir_function *f)
|
||||
emit_function(_mesa_glsl_parse_state *state, ir_function *f)
|
||||
{
|
||||
/* Emit the new function header */
|
||||
if (state->current_function == NULL) {
|
||||
instructions->push_tail(f);
|
||||
} else {
|
||||
/* IR invariants disallow function declarations or definitions nested
|
||||
* within other function definitions. Insert the new ir_function
|
||||
* block in the instruction sequence before the ir_function block
|
||||
* containing the current ir_function_signature.
|
||||
*/
|
||||
ir_function *const curr =
|
||||
const_cast<ir_function *>(state->current_function->function());
|
||||
|
||||
curr->insert_before(f);
|
||||
}
|
||||
/* IR invariants disallow function declarations or definitions
|
||||
* nested within other function definitions. But there is no
|
||||
* requirement about the relative order of function declarations
|
||||
* and definitions with respect to one another. So simply insert
|
||||
* the new ir_function block at the end of the toplevel instruction
|
||||
* list.
|
||||
*/
|
||||
state->toplevel_ir->push_tail(f);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3069,7 +3066,7 @@ ast_function::hir(exec_list *instructions,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
emit_function(state, instructions, f);
|
||||
emit_function(state, f);
|
||||
}
|
||||
|
||||
/* Verify the return type of main() */
|
||||
|
|
|
|||
|
|
@ -129,6 +129,12 @@ struct _mesa_glsl_parse_state {
|
|||
*/
|
||||
class ir_function_signature *current_function;
|
||||
|
||||
/**
|
||||
* During AST to IR conversion, pointer to the toplevel IR
|
||||
* instruction list being generated.
|
||||
*/
|
||||
exec_list *toplevel_ir;
|
||||
|
||||
/** Have we found a return statement in this function? */
|
||||
bool found_return;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue