[Mesa-stable] [Mesa-dev] [PATCH] glsl: Fix cross-version linking between VS and GS.
Ian Romanick
idr at freedesktop.org
Wed Nov 20 15:59:11 PST 2013
On 11/20/2013 02:15 PM, Paul Berry wrote:
> On 20 November 2013 11:35, Ian Romanick <idr at freedesktop.org
> <mailto:idr at freedesktop.org>> wrote:
>
> On 11/19/2013 06:11 PM, Paul Berry wrote:
> > 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".
>
> Which type do you get? What happens when the linked shader runs?
>
>
> The interface blocks get lowered to individual variable declarations by
> lower_named_interface_blocks.cpp, and then since these are built-ins,
> the linker isn't actually responsible for matching them up--they get
> matched up automatically by virtue of the ir_variable->location values
> that were preassigned by builtin_variables.cpp.
>
> So what happens when the shader runs is that the mismatch really has no
> consequence. For example, if we link a 1.10 VS with a 1.50 GS, and the
> GS tries to access gl_in[...].gl_ClipDistance, it gets undefined
> results, because the VS didn't write to gl_ClipDistance (it couldn't,
> because gl_ClipDistance didn't exist in 1.10). But that's no different
> from what would have happened if we had linked a 1.50 VS that didn't
> write gl_ClipDistance to a 1.50 GS that tried to read from gl_ClipDistance.
Ahh.. okay. Then with or without the minor change I suggested, this
patch is
Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
> Do we know what other implementations do for mixed VS / GS versions?
>
>
> My Nvidia system allows arbitrary mixing of VS / GS versions.
>
>
>
> > Cc: "10.0" <mesa-stable at lists.freedesktop.org
> <mailto:mesa-stable at 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);
>
> Would it be easier to just have
>
> explicitly_declared = (var->how_declared !=
> ir_var_declared_implicitly);
>
> after the existing if-block?
>
>
> Ok, sure. I don't have a strong feeling about this, so I'm happy to
> change it.
>
>
> > }
> > }
> >
> > @@ -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)
> >
>
>
More information about the mesa-stable
mailing list