linker: Refactor code that gets an input matching an output
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
@@ -1067,6 +1067,37 @@ populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a variable from the consumer that "matches" the specified variable
|
||||||
|
*
|
||||||
|
* This function only finds inputs with names that match. There is no
|
||||||
|
* validation (here) that the types, etc. are compatible.
|
||||||
|
*/
|
||||||
|
ir_variable *
|
||||||
|
get_matching_input(void *mem_ctx,
|
||||||
|
const ir_variable *output_var,
|
||||||
|
hash_table *consumer_inputs,
|
||||||
|
hash_table *consumer_interface_inputs)
|
||||||
|
{
|
||||||
|
ir_variable *input_var;
|
||||||
|
|
||||||
|
if (output_var->get_interface_type() != NULL) {
|
||||||
|
char *const iface_field_name =
|
||||||
|
ralloc_asprintf(mem_ctx, "%s.%s",
|
||||||
|
output_var->get_interface_type()->name,
|
||||||
|
output_var->name);
|
||||||
|
input_var =
|
||||||
|
(ir_variable *) hash_table_find(consumer_interface_inputs,
|
||||||
|
iface_field_name);
|
||||||
|
} else {
|
||||||
|
input_var =
|
||||||
|
(ir_variable *) hash_table_find(consumer_inputs, output_var->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (input_var == NULL || input_var->data.mode != ir_var_shader_in)
|
||||||
|
? NULL : input_var;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1142,23 +1173,9 @@ assign_varying_locations(struct gl_context *ctx,
|
|||||||
tfeedback_candidate_generator g(mem_ctx, tfeedback_candidates);
|
tfeedback_candidate_generator g(mem_ctx, tfeedback_candidates);
|
||||||
g.process(output_var);
|
g.process(output_var);
|
||||||
|
|
||||||
ir_variable *input_var;
|
ir_variable *const input_var =
|
||||||
if (output_var->get_interface_type() != NULL) {
|
linker::get_matching_input(mem_ctx, output_var, consumer_inputs,
|
||||||
char *const iface_field_name =
|
consumer_interface_inputs);
|
||||||
ralloc_asprintf(mem_ctx, "%s.%s",
|
|
||||||
output_var->get_interface_type()->name,
|
|
||||||
output_var->name);
|
|
||||||
input_var =
|
|
||||||
(ir_variable *) hash_table_find(consumer_interface_inputs,
|
|
||||||
iface_field_name);
|
|
||||||
} else {
|
|
||||||
input_var =
|
|
||||||
(ir_variable *) hash_table_find(consumer_inputs, output_var->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input_var && input_var->data.mode != ir_var_shader_in)
|
|
||||||
input_var = NULL;
|
|
||||||
|
|
||||||
if (input_var) {
|
if (input_var) {
|
||||||
matches.record(output_var, input_var);
|
matches.record(output_var, input_var);
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,12 @@ bool
|
|||||||
populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
|
populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
|
||||||
hash_table *consumer_inputs,
|
hash_table *consumer_inputs,
|
||||||
hash_table *consumer_interface_inputs);
|
hash_table *consumer_interface_inputs);
|
||||||
|
|
||||||
|
ir_variable *
|
||||||
|
get_matching_input(void *mem_ctx,
|
||||||
|
const ir_variable *output_var,
|
||||||
|
hash_table *consumer_inputs,
|
||||||
|
hash_table *consumer_interface_inputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
class link_varyings : public ::testing::Test {
|
class link_varyings : public ::testing::Test {
|
||||||
@@ -265,3 +271,77 @@ TEST_F(link_varyings, invalid_interface_input)
|
|||||||
consumer_inputs,
|
consumer_inputs,
|
||||||
consumer_interface_inputs));
|
consumer_interface_inputs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(link_varyings, interface_field_doesnt_match_noninterface)
|
||||||
|
{
|
||||||
|
char *const iface_field_name = interface_field_name(simple_interface);
|
||||||
|
|
||||||
|
/* The input shader has a single input variable name "a.v"
|
||||||
|
*/
|
||||||
|
ir_variable *const in_v =
|
||||||
|
new(mem_ctx) ir_variable(glsl_type::vec(4),
|
||||||
|
iface_field_name,
|
||||||
|
ir_var_shader_in);
|
||||||
|
|
||||||
|
ir.push_tail(in_v);
|
||||||
|
|
||||||
|
ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx,
|
||||||
|
&ir,
|
||||||
|
consumer_inputs,
|
||||||
|
consumer_interface_inputs));
|
||||||
|
|
||||||
|
/* Create an output variable, "v", that is part of an interface block named
|
||||||
|
* "a". They should not match.
|
||||||
|
*/
|
||||||
|
ir_variable *const out_v =
|
||||||
|
new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type,
|
||||||
|
simple_interface->fields.structure[0].name,
|
||||||
|
ir_var_shader_in);
|
||||||
|
|
||||||
|
out_v->init_interface_type(simple_interface);
|
||||||
|
|
||||||
|
ir_variable *const match =
|
||||||
|
linker::get_matching_input(mem_ctx,
|
||||||
|
out_v,
|
||||||
|
consumer_inputs,
|
||||||
|
consumer_interface_inputs);
|
||||||
|
|
||||||
|
EXPECT_EQ(NULL, match);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(link_varyings, interface_field_doesnt_match_noninterface_vice_versa)
|
||||||
|
{
|
||||||
|
char *const iface_field_name = interface_field_name(simple_interface);
|
||||||
|
|
||||||
|
/* In input shader has a single variable, "v", that is part of an interface
|
||||||
|
* block named "a".
|
||||||
|
*/
|
||||||
|
ir_variable *const in_v =
|
||||||
|
new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type,
|
||||||
|
simple_interface->fields.structure[0].name,
|
||||||
|
ir_var_shader_in);
|
||||||
|
|
||||||
|
in_v->init_interface_type(simple_interface);
|
||||||
|
|
||||||
|
ir.push_tail(in_v);
|
||||||
|
|
||||||
|
ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx,
|
||||||
|
&ir,
|
||||||
|
consumer_inputs,
|
||||||
|
consumer_interface_inputs));
|
||||||
|
|
||||||
|
/* Create an output variable "a.v". They should not match.
|
||||||
|
*/
|
||||||
|
ir_variable *const out_v =
|
||||||
|
new(mem_ctx) ir_variable(glsl_type::vec(4),
|
||||||
|
iface_field_name,
|
||||||
|
ir_var_shader_out);
|
||||||
|
|
||||||
|
ir_variable *const match =
|
||||||
|
linker::get_matching_input(mem_ctx,
|
||||||
|
out_v,
|
||||||
|
consumer_inputs,
|
||||||
|
consumer_interface_inputs);
|
||||||
|
|
||||||
|
EXPECT_EQ(NULL, match);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user