diff options
author | Paul Berry <[email protected]> | 2013-11-19 17:48:02 -0800 |
---|---|---|
committer | Paul Berry <[email protected]> | 2013-11-21 15:05:06 -0800 |
commit | 0f4cacbb53c23e4fa027375c492edd17b40ae748 (patch) | |
tree | 307c1bdceb7a8aa0626a77ed61eba8b4dd3931c4 /src/glsl/link_interface_blocks.cpp | |
parent | 2bbcf19acad530d339ffe8e007fe2f6a244e1580 (diff) |
glsl: Fix cross-version linking between VS and GS.
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" <[email protected]>
v2: In the interface_block_definition constructor, move the assignment
to explicitly_declared after the existing if block.
Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl/link_interface_blocks.cpp')
-rw-r--r-- | src/glsl/link_interface_blocks.cpp | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/glsl/link_interface_blocks.cpp b/src/glsl/link_interface_blocks.cpp index a7fceb9bad6..528d4a1577e 100644 --- a/src/glsl/link_interface_blocks.cpp +++ b/src/glsl/link_interface_blocks.cpp @@ -60,6 +60,7 @@ struct interface_block_definition if (var->type->is_array()) array_size = var->type->length; } + explicitly_declared = (var->how_declared != ir_var_declared_implicitly); } /** @@ -77,6 +78,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 +98,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 +157,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) |