diff options
author | Kenneth Graunke <[email protected]> | 2013-05-20 23:46:16 -0700 |
---|---|---|
committer | Jordan Justen <[email protected]> | 2013-05-23 09:37:12 -0700 |
commit | 3ddfccb303c571f83de7a0743021eda922c5c8a1 (patch) | |
tree | 47ea40b338cf8c2686748aedfcdebe994d5ff9ff /src/glsl/link_interface_blocks.cpp | |
parent | 4a0bcd90cff6701aaf08d9bbcf6144b18c2d8284 (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.cpp | 39 |
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; +} |