summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2013-10-02 18:01:13 -0700
committerIan Romanick <[email protected]>2014-05-02 07:19:40 -0700
commitfe37cb0ac67071759a88ea767027368399e1fdb6 (patch)
treeea6d95da0737b30c3710d2b1398100e25514e805 /src/glsl
parent5699220cd5719be6fbafdefd75025a817bcb200a (diff)
linker: Refactor code that gets an input matching an output
Signed-off-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/link_varyings.cpp51
-rw-r--r--src/glsl/tests/varyings_test.cpp80
2 files changed, 114 insertions, 17 deletions
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 8935c89fdb0..9b5ae3e9410 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -1067,6 +1067,37 @@ populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
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);
g.process(output_var);
- 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);
- }
-
- if (input_var && input_var->data.mode != ir_var_shader_in)
- input_var = NULL;
-
+ ir_variable *const input_var =
+ linker::get_matching_input(mem_ctx, output_var, consumer_inputs,
+ consumer_interface_inputs);
if (input_var) {
matches.record(output_var, input_var);
}
diff --git a/src/glsl/tests/varyings_test.cpp b/src/glsl/tests/varyings_test.cpp
index 76a08e32cf3..174911245f7 100644
--- a/src/glsl/tests/varyings_test.cpp
+++ b/src/glsl/tests/varyings_test.cpp
@@ -39,6 +39,12 @@ bool
populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
hash_table *consumer_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 {
@@ -265,3 +271,77 @@ TEST_F(link_varyings, invalid_interface_input)
consumer_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);
+}