[Mesa-dev] [PATCH 3/3] glsl: don't always reject shaders with mismatching ifc blocks

Samuel Iglesias Gonsálvez siglesias at igalia.com
Tue Mar 8 15:24:55 UTC 2016


On Wed, 2016-03-09 at 00:47 +1100, Timothy Arceri wrote:
> Since we store some member qualifiers in the interface type
> we need to be more careful about rejecting shaders just because
> the pointer doesn't match. Its perfectly valid for some qualifiers
> such as precision to not match across shader interfaces.
> ---
>  src/compiler/glsl/link_interface_blocks.cpp | 78
> ++++++++++++++++++++++++++---
>  1 file changed, 72 insertions(+), 6 deletions(-)
> 
> diff --git a/src/compiler/glsl/link_interface_blocks.cpp
> b/src/compiler/glsl/link_interface_blocks.cpp
> index 9d36836..f868c99 100644
> --- a/src/compiler/glsl/link_interface_blocks.cpp
> +++ b/src/compiler/glsl/link_interface_blocks.cpp
> @@ -81,6 +81,66 @@ intrastage_match(ir_variable *a,
>     return true;
>  }
>  
> +/**
> + * Return true if interface members mismatch and its not allowed by
> GLSL.
> + */
> +static bool
> +interstage_member_mismatch(struct gl_shader_program *prog,
> +                           const glsl_type *c, const glsl_type *p) {
> +
> +   if (c->length != p->length)
> +      return true;
> +
> +   for (unsigned i = 0; i < c->length; i++) {
> +      if (c->fields.structure[i].type != p-
> >fields.structure[i].type)
> +         return true;
> +      if (strcmp(c->fields.structure[i].name,
> +                 p->fields.structure[i].name) != 0)
> +         return true;
> +      if (c->fields.structure[i].location
> +          != p->fields.structure[i].location)

Just one comment, I usually see the relational operator at the end of
the previous line, although there are several examples in Mesa like
this. I checked the coding style and I have not found any reference of
the preferred way.

In any case, the series is:

Reviewed-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>

Sam

> +         return true;
> +      if (c->fields.structure[i].patch
> +          != p->fields.structure[i].patch)
> +         return true;
> +
> +      /* From Section 4.5 (Interpolation Qualifiers) of the GLSL
> 4.40 spec:
> +       *
> +       *    "It is a link-time error if, within the same stage, the
> +       *    interpolation qualifiers of variables of the same name
> do not
> +       *    match."
> +       */
> +      if (prog->IsES || prog->Version < 440)
> +         if (c->fields.structure[i].interpolation
> +             != p->fields.structure[i].interpolation)
> +            return true;
> +
> +      /* From Section 4.3.4 (Input Variables) of the GLSL ES 3.0
> spec:
> +       *
> +       *    "The output of the vertex shader and the input of the
> fragment
> +       *    shader form an interface.  For this interface, vertex
> shader
> +       *    output variables and fragment shader input variables of
> the same
> +       *    name must match in type and qualification (other than
> precision
> +       *    and out matching to in).
> +       *
> +       * The table in Section 9.2.1 Linked Shaders of the GLSL ES
> 3.1 spec
> +       * says that centroid no longer needs to match for varyings.
> +       *
> +       * The table in Section 9.2.1 Linked Shaders of the GLSL ES
> 3.2 spec
> +       * says that sample need not match for varyings.
> +       */
> +      if (!prog->IsES || prog->Version < 310)
> +         if (c->fields.structure[i].centroid
> +             != p->fields.structure[i].centroid)
> +            return true;
> +      if (!prog->IsES || prog->Version < 320)
> +         if (c->fields.structure[i].sample
> +             != p->fields.structure[i].sample)
> +            return true;
> +   }
> +
> +   return false;
> +}
>  
>  /**
>   * Check if two interfaces match, according to interstage (in/out)
> interface
> @@ -91,9 +151,8 @@ intrastage_match(ir_variable *a,
>   * This is used for tessellation control and geometry shader
> consumers.
>   */
>  static bool
> -interstage_match(ir_variable *producer,
> -                 ir_variable *consumer,
> -                 bool extra_array_level)
> +interstage_match(struct gl_shader_program *prog, ir_variable
> *producer,
> +                 ir_variable *consumer, bool extra_array_level)
>  {
>     /* Unsized arrays should not occur during interstage
> linking.  They
>      * should have all been assigned a size by
> link_intrastage_shaders.
> @@ -106,9 +165,16 @@ interstage_match(ir_variable *producer,
>        /* 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.
> +       *
> +       * Also we store some member information in glsl_type that
> doesn't
> +       * always have to match across shaders such as interpolation
> so we need
> +       * to make a pass over members glsl_struct_field to make sure
> we don't
> +       * reject shaders where fields don't need to match.
>         */
> -      if (consumer->data.how_declared != ir_var_declared_implicitly
> ||
> -          producer->data.how_declared != ir_var_declared_implicitly)
> +      if ((consumer->data.how_declared != ir_var_declared_implicitly
> ||
> +           producer->data.how_declared !=
> ir_var_declared_implicitly) &&
> +          interstage_member_mismatch(prog, consumer-
> >get_interface_type(),
> +                                     producer-
> >get_interface_type()))
>           return false;
>     }
>  
> @@ -311,7 +377,7 @@ validate_interstage_inout_blocks(struct
> gl_shader_program *prog,
>        if (consumer_def == NULL)
>           continue;
>  
> -      if (!interstage_match(var, consumer_def, extra_array_level)) {
> +      if (!interstage_match(prog, var, consumer_def,
> extra_array_level)) {
>           linker_error(prog, "definitions of interface block `%s' do
> not "
>                        "match\n", var->get_interface_type()->name);
>           return;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160308/ee3ea06c/attachment.sig>


More information about the mesa-dev mailing list