Mesa (master): glsl: Fix cross-version linking between VS and GS.

Paul Berry stereotype441 at kemper.freedesktop.org
Thu Nov 21 23:25:32 UTC 2013


Module: Mesa
Branch: master
Commit: 0f4cacbb53c23e4fa027375c492edd17b40ae748
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0f4cacbb53c23e4fa027375c492edd17b40ae748

Author: Paul Berry <stereotype441 at gmail.com>
Date:   Tue Nov 19 17:48:02 2013 -0800

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" <mesa-stable at lists.freedesktop.org>

v2: In the interface_block_definition constructor, move the assignment
to explicitly_declared after the existing if block.

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

---

 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 a7fceb9..528d4a1 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)




More information about the mesa-commit mailing list