mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 02:10:11 +01:00
glsl: apply implicit matching rules when linking
Previously when linking i.e. when compiler state was NULL. We just assumed all implicit matching was avaliable. Acked-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30752>
This commit is contained in:
parent
018ebeca72
commit
8e4b14dcfd
11 changed files with 80 additions and 33 deletions
|
|
@ -704,6 +704,8 @@ match_function_by_name(const char *name,
|
|||
/* Look for a match in the local shader. If exact, we're done. */
|
||||
bool is_exact = false;
|
||||
sig = local_sig = f->matching_signature(state, actual_parameters,
|
||||
state->has_implicit_conversions(),
|
||||
state->has_implicit_int_to_uint_conversion(),
|
||||
allow_builtins, &is_exact);
|
||||
if (is_exact)
|
||||
return sig;
|
||||
|
|
@ -755,6 +757,8 @@ match_subroutine_by_name(const char *name,
|
|||
return NULL;
|
||||
*var_r = var;
|
||||
sig = found->matching_signature(state, actual_parameters,
|
||||
state->has_implicit_conversions(),
|
||||
state->has_implicit_int_to_uint_conversion(),
|
||||
false, &is_exact);
|
||||
return sig;
|
||||
}
|
||||
|
|
@ -1162,7 +1166,9 @@ implicitly_convert_component(ir_rvalue * &from, const glsl_base_type to,
|
|||
from->type->vector_elements,
|
||||
from->type->matrix_columns);
|
||||
|
||||
if (_mesa_glsl_can_implicitly_convert(from->type, desired_type, state)) {
|
||||
if (_mesa_glsl_can_implicitly_convert(from->type, desired_type,
|
||||
state->has_implicit_conversions(),
|
||||
state->has_implicit_int_to_uint_conversion())) {
|
||||
/* Even though convert_component() implements the constructor
|
||||
* conversion rules (not the implicit conversion rules), its safe
|
||||
* to use it here because we already checked that the implicit
|
||||
|
|
|
|||
|
|
@ -6448,6 +6448,8 @@ ast_function::hir(exec_list *instructions,
|
|||
continue;
|
||||
|
||||
tsig = fn->matching_signature(state, &sig->parameters,
|
||||
state->has_implicit_conversions(),
|
||||
state->has_implicit_int_to_uint_conversion(),
|
||||
false);
|
||||
if (!tsig) {
|
||||
_mesa_glsl_error(& loc, state, "subroutine type mismatch '%s' - signatures do not match\n", decl->identifier);
|
||||
|
|
@ -7152,7 +7154,9 @@ ast_case_label::hir(exec_list *instructions,
|
|||
|
||||
/* Check if int->uint implicit conversion is supported. */
|
||||
bool integer_conversion_supported =
|
||||
_mesa_glsl_can_implicitly_convert(&glsl_type_builtin_int, &glsl_type_builtin_uint, state);
|
||||
_mesa_glsl_can_implicitly_convert(&glsl_type_builtin_int, &glsl_type_builtin_uint,
|
||||
state->has_implicit_conversions(),
|
||||
state->has_implicit_int_to_uint_conversion());
|
||||
|
||||
if ((!glsl_type_is_integer_32(type_a) || !glsl_type_is_integer_32(type_b)) ||
|
||||
!integer_conversion_supported) {
|
||||
|
|
|
|||
|
|
@ -1461,7 +1461,10 @@ builtin_builder::find(_mesa_glsl_parse_state *state,
|
|||
return NULL;
|
||||
|
||||
ir_function_signature *sig =
|
||||
f->matching_signature(state, actual_parameters, true);
|
||||
f->matching_signature(state, actual_parameters,
|
||||
state->has_implicit_conversions(),
|
||||
state->has_implicit_int_to_uint_conversion(),
|
||||
true);
|
||||
if (sig == NULL)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -9051,7 +9054,7 @@ _mesa_get_main_function_signature(glsl_symbol_table *symbols)
|
|||
* shaders) because that would have already been caught above.
|
||||
*/
|
||||
ir_function_signature *sig =
|
||||
f->matching_signature(NULL, &void_parameters, false);
|
||||
f->matching_signature(NULL, &void_parameters, false, false, false);
|
||||
if ((sig != NULL) && sig->is_defined) {
|
||||
return sig;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -960,16 +960,14 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
|
|||
|
||||
bool
|
||||
_mesa_glsl_can_implicitly_convert(const glsl_type *from, const glsl_type *desired,
|
||||
_mesa_glsl_parse_state *state)
|
||||
bool has_implicit_conversions,
|
||||
bool has_implicit_int_to_uint_conversion)
|
||||
{
|
||||
if (from == desired)
|
||||
return true;
|
||||
|
||||
/* GLSL 1.10 and ESSL do not allow implicit conversions. If there is no
|
||||
* state, we're doing intra-stage function linking where these checks have
|
||||
* already been done.
|
||||
*/
|
||||
if (state && !state->has_implicit_conversions())
|
||||
/* GLSL 1.10 and ESSL do not allow implicit conversions. */
|
||||
if (!has_implicit_conversions)
|
||||
return false;
|
||||
|
||||
/* There is no conversion among matrix types. */
|
||||
|
|
@ -991,8 +989,8 @@ _mesa_glsl_can_implicitly_convert(const glsl_type *from, const glsl_type *desire
|
|||
* state-dependent checks have already happened though, so allow anything
|
||||
* that's allowed in any shader version.
|
||||
*/
|
||||
if ((!state || state->has_implicit_int_to_uint_conversion()) &&
|
||||
desired->base_type == GLSL_TYPE_UINT && from->base_type == GLSL_TYPE_INT)
|
||||
if (has_implicit_int_to_uint_conversion &&
|
||||
desired->base_type == GLSL_TYPE_UINT && from->base_type == GLSL_TYPE_INT)
|
||||
return true;
|
||||
|
||||
/* No implicit conversions from double. */
|
||||
|
|
|
|||
|
|
@ -1087,7 +1087,8 @@ extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
|
|||
* \endverbatim
|
||||
*/
|
||||
extern bool _mesa_glsl_can_implicitly_convert(const glsl_type *from, const glsl_type *desired,
|
||||
_mesa_glsl_parse_state *state);
|
||||
bool has_implicit_conversions,
|
||||
bool has_implicit_int_to_uint_conversion);
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
|
|
|||
|
|
@ -1313,6 +1313,8 @@ public:
|
|||
*/
|
||||
ir_function_signature *matching_signature(_mesa_glsl_parse_state *state,
|
||||
const exec_list *actual_param,
|
||||
bool has_implicit_conversions,
|
||||
bool has_implicit_int_to_uint_conversion,
|
||||
bool allow_builtins,
|
||||
bool *match_is_exact);
|
||||
|
||||
|
|
@ -1322,6 +1324,8 @@ public:
|
|||
*/
|
||||
ir_function_signature *matching_signature(_mesa_glsl_parse_state *state,
|
||||
const exec_list *actual_param,
|
||||
bool has_implicit_conversions,
|
||||
bool has_implicit_int_to_uint_conversion,
|
||||
bool allow_builtins);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ get_param_type(const ir_instruction *inst)
|
|||
* \see matching_signature()
|
||||
*/
|
||||
static parameter_list_match_t
|
||||
parameter_lists_match(_mesa_glsl_parse_state *state,
|
||||
parameter_lists_match(bool has_implicit_conversions,
|
||||
bool has_implicit_int_to_uint_conversion,
|
||||
const exec_list *list_a, const exec_list *list_b)
|
||||
{
|
||||
const exec_node *node_a = list_a->get_head_raw();
|
||||
|
|
@ -99,12 +100,16 @@ parameter_lists_match(_mesa_glsl_parse_state *state,
|
|||
case ir_var_const_in:
|
||||
case ir_var_function_in:
|
||||
if (param->data.implicit_conversion_prohibited ||
|
||||
!_mesa_glsl_can_implicitly_convert(actual_type, param->type, state))
|
||||
!_mesa_glsl_can_implicitly_convert(actual_type, param->type,
|
||||
has_implicit_conversions,
|
||||
has_implicit_int_to_uint_conversion))
|
||||
return PARAMETER_LIST_NO_MATCH;
|
||||
break;
|
||||
|
||||
case ir_var_function_out:
|
||||
if (!_mesa_glsl_can_implicitly_convert(param->type, actual_type, state))
|
||||
if (!_mesa_glsl_can_implicitly_convert(param->type, actual_type,
|
||||
has_implicit_conversions,
|
||||
has_implicit_int_to_uint_conversion))
|
||||
return PARAMETER_LIST_NO_MATCH;
|
||||
break;
|
||||
|
||||
|
|
@ -305,16 +310,21 @@ choose_best_inexact_overload(_mesa_glsl_parse_state *state,
|
|||
ir_function_signature *
|
||||
ir_function::matching_signature(_mesa_glsl_parse_state *state,
|
||||
const exec_list *actual_parameters,
|
||||
bool has_implicit_conversions,
|
||||
bool has_implicit_int_to_uint_conversion,
|
||||
bool allow_builtins)
|
||||
{
|
||||
bool is_exact;
|
||||
return matching_signature(state, actual_parameters, allow_builtins,
|
||||
&is_exact);
|
||||
return matching_signature(state, actual_parameters, has_implicit_conversions,
|
||||
has_implicit_int_to_uint_conversion,
|
||||
allow_builtins, &is_exact);
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
ir_function::matching_signature(_mesa_glsl_parse_state *state,
|
||||
const exec_list *actual_parameters,
|
||||
bool has_implicit_conversions,
|
||||
bool has_implicit_int_to_uint_conversion,
|
||||
bool allow_builtins,
|
||||
bool *is_exact)
|
||||
{
|
||||
|
|
@ -339,7 +349,9 @@ ir_function::matching_signature(_mesa_glsl_parse_state *state,
|
|||
!sig->is_builtin_available(state)))
|
||||
continue;
|
||||
|
||||
switch (parameter_lists_match(state, & sig->parameters, actual_parameters)) {
|
||||
switch (parameter_lists_match(has_implicit_conversions,
|
||||
has_implicit_int_to_uint_conversion,
|
||||
&sig->parameters, actual_parameters)) {
|
||||
case PARAMETER_LIST_EXACT_MATCH:
|
||||
*is_exact = true;
|
||||
free(inexact_matches);
|
||||
|
|
|
|||
|
|
@ -687,7 +687,10 @@ ir_reader::read_call(s_expression *expr)
|
|||
}
|
||||
|
||||
ir_function_signature *callee =
|
||||
f->matching_signature(state, ¶meters, true);
|
||||
f->matching_signature(state, ¶meters,
|
||||
state->has_implicit_conversions(),
|
||||
state->has_implicit_int_to_uint_conversion(),
|
||||
true);
|
||||
if (callee == NULL) {
|
||||
ir_read_error(expr, "couldn't find matching signature for function "
|
||||
"%s", name->value());
|
||||
|
|
|
|||
|
|
@ -32,20 +32,24 @@
|
|||
|
||||
static ir_function_signature *
|
||||
find_matching_signature(const char *name, const exec_list *actual_parameters,
|
||||
glsl_symbol_table *symbols);
|
||||
glsl_symbol_table *symbols,
|
||||
bool has_implicit_conversions,
|
||||
bool has_implicit_int_to_uint_conversion);
|
||||
|
||||
namespace {
|
||||
|
||||
class call_link_visitor : public ir_hierarchical_visitor {
|
||||
public:
|
||||
call_link_visitor(gl_shader_program *prog, gl_linked_shader *linked,
|
||||
gl_shader **shader_list, unsigned num_shaders)
|
||||
gl_shader *main, gl_shader **shader_list,
|
||||
unsigned num_shaders)
|
||||
{
|
||||
this->prog = prog;
|
||||
this->shader_list = shader_list;
|
||||
this->num_shaders = num_shaders;
|
||||
this->success = true;
|
||||
this->linked = linked;
|
||||
this->main = main;
|
||||
|
||||
this->locals = _mesa_pointer_set_create(NULL);
|
||||
}
|
||||
|
|
@ -81,7 +85,9 @@ public:
|
|||
* final linked shader. If it does, use it as the target of the call.
|
||||
*/
|
||||
ir_function_signature *sig =
|
||||
find_matching_signature(name, &callee->parameters, linked->symbols);
|
||||
find_matching_signature(name, &callee->parameters, linked->symbols,
|
||||
main->has_implicit_conversions,
|
||||
main->has_implicit_int_to_uint_conversion);
|
||||
if (sig != NULL) {
|
||||
ir->callee = sig;
|
||||
return visit_continue;
|
||||
|
|
@ -92,7 +98,9 @@ public:
|
|||
*/
|
||||
for (unsigned i = 0; i < num_shaders; i++) {
|
||||
sig = find_matching_signature(name, &ir->actual_parameters,
|
||||
shader_list[i]->symbols);
|
||||
shader_list[i]->symbols,
|
||||
shader_list[i]->has_implicit_conversions,
|
||||
shader_list[i]->has_implicit_int_to_uint_conversion);
|
||||
if (sig)
|
||||
break;
|
||||
}
|
||||
|
|
@ -299,6 +307,8 @@ private:
|
|||
*/
|
||||
gl_linked_shader *linked;
|
||||
|
||||
gl_shader *main;
|
||||
|
||||
/**
|
||||
* Table of variables local to the function.
|
||||
*/
|
||||
|
|
@ -312,13 +322,17 @@ private:
|
|||
*/
|
||||
ir_function_signature *
|
||||
find_matching_signature(const char *name, const exec_list *actual_parameters,
|
||||
glsl_symbol_table *symbols)
|
||||
glsl_symbol_table *symbols,
|
||||
bool has_implicit_conversions,
|
||||
bool has_implicit_int_to_uint_conversion)
|
||||
{
|
||||
ir_function *const f = symbols->get_function(name);
|
||||
|
||||
if (f) {
|
||||
ir_function_signature *sig =
|
||||
f->matching_signature(NULL, actual_parameters, false);
|
||||
f->matching_signature(NULL, actual_parameters,
|
||||
has_implicit_conversions,
|
||||
has_implicit_int_to_uint_conversion, false);
|
||||
|
||||
if (sig && (sig->is_defined || sig->is_intrinsic()))
|
||||
return sig;
|
||||
|
|
@ -329,11 +343,12 @@ find_matching_signature(const char *name, const exec_list *actual_parameters,
|
|||
|
||||
|
||||
bool
|
||||
link_function_calls(gl_shader_program *prog, gl_linked_shader *main,
|
||||
gl_shader **shader_list, unsigned num_shaders)
|
||||
link_function_calls(gl_shader_program *prog, gl_linked_shader *main_linked,
|
||||
gl_shader *main, gl_shader **shader_list,
|
||||
unsigned num_shaders)
|
||||
{
|
||||
call_link_visitor v(prog, main, shader_list, num_shaders);
|
||||
call_link_visitor v(prog, main_linked, main, shader_list, num_shaders);
|
||||
|
||||
v.run(main->ir);
|
||||
v.run(main_linked->ir);
|
||||
return v.success;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1683,7 +1683,7 @@ link_intrastage_shaders(void *mem_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
if (!link_function_calls(prog, linked, shader_list, num_shaders)) {
|
||||
if (!link_function_calls(prog, linked, main, shader_list, num_shaders)) {
|
||||
_mesa_delete_linked_shader(ctx, linked);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@ struct gl_shader;
|
|||
struct gl_linked_shader;
|
||||
|
||||
extern bool
|
||||
link_function_calls(gl_shader_program *prog, gl_linked_shader *main,
|
||||
gl_shader **shader_list, unsigned num_shaders);
|
||||
link_function_calls(gl_shader_program *prog, gl_linked_shader *main_linked,
|
||||
gl_shader *main, gl_shader **shader_list,
|
||||
unsigned num_shaders);
|
||||
|
||||
bool
|
||||
validate_intrastage_arrays(struct gl_shader_program *prog,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue