[Mesa-dev] [PATCH 3/3] glsl: don't always reject shaders with mismatching ifc blocks
Timothy Arceri
timothy.arceri at collabora.com
Tue Mar 8 21:57:46 UTC 2016
On Tue, 2016-03-08 at 16:24 +0100, Samuel Iglesias Gonsálvez wrote:
> 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.
Right that is the suggested way for new code, this was copy and pasted
so forgot about that. Will fix before pushing.
>
> In any case, the series is:
>
> Reviewed-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
>
Thanks.
> 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);
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list