Previously, when attempting to link a vertex shader and a geometry shader that use different GLSL versions, we would sometimes generate a link error due to the implicit declaration of gl_PerVertex being different between the two GLSL versions.
This patch fixes that problem by only requiring interface block definitions to match when they are explicitly declared. Fixes piglit test "shaders/version-mixing vs-gs". Cc: "10.0" <mesa-sta...@lists.freedesktop.org> --- This patch depends on "[PATCH v2] glsl: Prohibit illegal mixing of redeclarations inside/outside gl_PerVertex.", which was sent out for review earlier today. src/glsl/link_interface_blocks.cpp | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/glsl/link_interface_blocks.cpp b/src/glsl/link_interface_blocks.cpp index a7fceb9..b4379b0 100644 --- a/src/glsl/link_interface_blocks.cpp +++ b/src/glsl/link_interface_blocks.cpp @@ -59,6 +59,9 @@ struct interface_block_definition instance_name = var->name; if (var->type->is_array()) array_size = var->type->length; + explicitly_declared = (var->how_declared == ir_var_declared_normally); + } else { + explicitly_declared = (var->how_declared == ir_var_declared_in_block); } } @@ -77,6 +80,12 @@ struct interface_block_definition * Otherwise -1. */ int array_size; + + /** + * True if this interface block was explicitly declared in the shader; + * false if it was an implicitly declared built-in interface block. + */ + bool explicitly_declared; }; @@ -91,8 +100,14 @@ intrastage_match(interface_block_definition *a, ir_variable_mode mode) { /* Types must match. */ - if (a->type != b->type) - return false; + if (a->type != b->type) { + /* Exception: if both the interface blocks are implicitly declared, + * don't force their types to match. They might mismatch due to the two + * shaders using different GLSL versions, and that's ok. + */ + if (a->explicitly_declared || b->explicitly_declared) + return false; + } /* Presence/absence of interface names must match. */ if ((a->instance_name == NULL) != (b->instance_name == NULL)) @@ -144,8 +159,14 @@ interstage_match(const interface_block_definition *producer, assert(producer->array_size != 0); /* Types must match. */ - if (consumer->type != producer->type) - return false; + if (consumer->type != producer->type) { + /* Exception: if both the interface blocks are implicitly declared, + * don't force their types to match. They might mismatch due to the two + * shaders using different GLSL versions, and that's ok. + */ + if (consumer->explicitly_declared || producer->explicitly_declared) + return false; + } if (extra_array_level) { /* Consumer must be an array, and producer must not. */ if (consumer->array_size == -1) -- 1.8.4.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev