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 <kenneth@whitecape.org>
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Kenneth Graunke
2013-05-20 23:46:16 -07:00
committed by Jordan Justen
parent 4a0bcd90cf
commit 3ddfccb303
3 changed files with 49 additions and 0 deletions
+39
View File
@@ -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;
}