summaryrefslogtreecommitdiffstats
path: root/src/glsl/link_interface_blocks.cpp
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2013-11-19 17:48:02 -0800
committerPaul Berry <[email protected]>2013-11-21 15:05:06 -0800
commit0f4cacbb53c23e4fa027375c492edd17b40ae748 (patch)
tree307c1bdceb7a8aa0626a77ed61eba8b4dd3931c4 /src/glsl/link_interface_blocks.cpp
parent2bbcf19acad530d339ffe8e007fe2f6a244e1580 (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.cpp27
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)