summaryrefslogtreecommitdiffstats
path: root/src/glsl/link_interface_blocks.cpp
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2013-05-20 23:46:16 -0700
committerJordan Justen <[email protected]>2013-05-23 09:37:12 -0700
commit3ddfccb303c571f83de7a0743021eda922c5c8a1 (patch)
tree47ea40b338cf8c2686748aedfcdebe994d5ff9ff /src/glsl/link_interface_blocks.cpp
parent4a0bcd90cff6701aaf08d9bbcf6144b18c2d8284 (diff)
glsl linker: compare interface blocks during interstage linking
Verify that interface blocks match when linking separate shader stages into a program. Fixes piglit glsl-1.50 tests: * linker/interface-blocks-vs-fs-member-count-mismatch.shader_test * linker/interface-blocks-vs-fs-member-order-mismatch.shader_test Signed-off-by: Kenneth Graunke <[email protected]> Signed-off-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src/glsl/link_interface_blocks.cpp')
-rw-r--r--src/glsl/link_interface_blocks.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/glsl/link_interface_blocks.cpp b/src/glsl/link_interface_blocks.cpp
index 4a4c5a14c72..b91860d0394 100644
--- a/src/glsl/link_interface_blocks.cpp
+++ b/src/glsl/link_interface_blocks.cpp
@@ -69,3 +69,42 @@ validate_intrastage_interface_blocks(const gl_shader **shader_list,
return true;
}
+
+bool
+validate_interstage_interface_blocks(const gl_shader *producer,
+ const gl_shader *consumer)
+{
+ glsl_symbol_table interfaces;
+
+ /* Add non-output interfaces from the consumer to the symbol table. */
+ foreach_list(node, consumer->ir) {
+ ir_variable *var = ((ir_instruction *) node)->as_variable();
+ if (!var || !var->interface_type || var->mode == ir_var_shader_out)
+ continue;
+
+ interfaces.add_interface(var->interface_type->name,
+ var->interface_type,
+ (enum ir_variable_mode) var->mode);
+ }
+
+ /* Verify that the producer's interfaces match. */
+ foreach_list(node, producer->ir) {
+ ir_variable *var = ((ir_instruction *) node)->as_variable();
+ if (!var || !var->interface_type || var->mode == ir_var_shader_in)
+ continue;
+
+ enum ir_variable_mode consumer_mode =
+ var->mode == ir_var_uniform ? ir_var_uniform : ir_var_shader_in;
+ const glsl_type *expected_type =
+ interfaces.get_interface(var->interface_type->name, consumer_mode);
+
+ /* The consumer doesn't use this output block. Ignore it. */
+ if (expected_type == NULL)
+ continue;
+
+ if (var->interface_type != expected_type)
+ return false;
+ }
+
+ return true;
+}