<p dir="ltr">---- Mark Janes wrote ----</p>
<p dir="ltr">> Timothy Arceri <<a href="mailto:t_arceri@yahoo.com.au">t_arceri@yahoo.com.au</a>> writes:<br>
> <br>
> > Use common intrastage array validation for interface blocks. This change also allows us to support interface blocks that are arrays of arrays.<br>
> <br>
> Please wrap this message to fit within 80 columns.<br>
> <br>
> > ---<br>
> >  src/glsl/link_interface_blocks.cpp | 76 ++++++++++++++++++--------------------<br>
> >  1 file changed, 35 insertions(+), 41 deletions(-)<br>
> ><br>
> > diff --git a/src/glsl/link_interface_blocks.cpp b/src/glsl/link_interface_blocks.cpp<br>
> > index 0ce502d..9000a3c 100644<br>
> > --- a/src/glsl/link_interface_blocks.cpp<br>
> > +++ b/src/glsl/link_interface_blocks.cpp<br>
> > @@ -50,18 +50,20 @@ struct interface_block_definition<br>
> >      * represents either the interface instance (for named interfaces), or a<br>
> >      * member of the interface (for unnamed interfaces).<br>
> >      */<br>
> > -   explicit interface_block_definition(const ir_variable *var)<br>
> > -      : type(var->get_interface_type()),<br>
> > -        instance_name(NULL),<br>
> > -        array_size(-1)<br>
> > +   explicit interface_block_definition(ir_variable *var)<br>
> > +      : var(var),<br>
> > +        type(var->get_interface_type()),<br>
> > +        instance_name(NULL)<br>
> >     {<br>
> >        if (var->is_interface_instance()) {<br>
> >           instance_name = var->name;<br>
> > -         if (var->type->is_array())<br>
> > -            array_size = var->type->length;<br>
> >        }<br>
> >        explicitly_declared = (var->data.how_declared != ir_var_declared_implicitly);<br>
> >     }<br>
> > +   /**<br>
> > +    * Interface block ir_variable<br>
> > +    */<br>
> > +   ir_variable *var;<br>
> >  <br>
> >     /**<br>
> >      * Interface block type<br>
> > @@ -74,12 +76,6 @@ struct interface_block_definition<br>
> >     const char *instance_name;<br>
> >  <br>
> >     /**<br>
> > -    * For an interface block array, the array size (or 0 if unsized).<br>
> > -    * Otherwise -1.<br>
> > -    */<br>
> > -   int array_size;<br>
> > -<br>
> > -   /**<br>
> >      * True if this interface block was explicitly declared in the shader;<br>
> >      * false if it was an implicitly declared built-in interface block.<br>
> >      */<br>
> > @@ -95,7 +91,8 @@ struct interface_block_definition<br>
> >  bool<br>
> >  intrastage_match(interface_block_definition *a,<br>
> >                   const interface_block_definition *b,<br>
>                     ^^^^^<br>
> I think the intent of this declaration is that b should not change (see below).<br>
> <br>
> > -                 ir_variable_mode mode)<br>
> > +                 ir_variable_mode mode,<br>
> > +                 struct gl_shader_program *prog)<br>
> >  {<br>
> >     /* Types must match. */<br>
> >     if (a->type != b->type) {<br>
> > @@ -120,18 +117,13 @@ intrastage_match(interface_block_definition *a,<br>
> >        return false;<br>
> >     }<br>
> >  <br>
> > -   /* Array vs. nonarray must be consistent, and sizes must be<br>
> > -    * consistent, with the exception that unsized arrays match sized<br>
> > -    * arrays.<br>
> > +   /* If a block is an array then it must match across the shader.<br>
> > +    * Unsized arrays are also processed and matched agaist sized arrays.<br>
> >      */<br>
> > -   if ((a->array_size == -1) != (b->array_size == -1))<br>
> > +   if (b->var->type != a->var->type &&<br>
> > +       (b->instance_name != NULL || a->instance_name != NULL) &&<br>
> > +       !validate_intrastage_arrays(prog, b->var, a->var))<br>
> <br>
> you pass a b's var member into validate_intrastage_arrays, where it may<br>
> be modified (due to your second patch in this series).  Is that your intention?<br>
> <br>
> It doesn't seem to affect any piglit tests.</p>
<p dir="ltr">Patch 2 may have been a result of me passing the a and b values in the wrong order when I started development, I will check this.</p>
<p dir="ltr">> <br>
> >        return false;<br>
> > -   if (b->array_size != 0) {<br>
> > -      if (a->array_size == 0)<br>
> > -         a->array_size = b->array_size;<br>
> > -      else if (a->array_size != b->array_size)<br>
> > -         return false;<br>
> > -   }<br>
> >  <br>
> >     return true;<br>
> >  }<br>
> > @@ -150,12 +142,6 @@ interstage_match(const interface_block_definition *producer,<br>
> >                   const interface_block_definition *consumer,<br>
> >                   bool extra_array_level)<br>
> >  {<br>
> > -   /* Unsized arrays should not occur during interstage linking.  They<br>
> > -    * should have all been assigned a size by link_intrastage_shaders.<br>
> > -    */<br>
> > -   assert(consumer->array_size != 0);<br>
> > -   assert(producer->array_size != 0);<br>
> > -<br>
> >     /* Types must match. */<br>
> >     if (consumer->type != producer->type) {<br>
> >        /* Exception: if both the interface blocks are implicitly declared,<br>
> > @@ -165,20 +151,27 @@ interstage_match(const interface_block_definition *producer,<br>
> >        if (consumer->explicitly_declared || producer->explicitly_declared)<br>
> >           return false;<br>
> >     }<br>
> > +<br>
> > +   /* Ignore outermost array if geom shader */<br>
> > +   const glsl_type *consumer_instance_type;<br>
> >     if (extra_array_level) {<br>
> > -      /* Consumer must be an array, and producer must not. */<br>
> > -      if (consumer->array_size == -1)<br>
> > -         return false;<br>
> > -      if (producer->array_size != -1)<br>
> > -         return false;<br>
> > +      consumer_instance_type = consumer->var->type->fields.array;<br>
> >     } else {<br>
> > -      /* Array vs. nonarray must be consistent, and sizes must be consistent.<br>
> > -       * Since unsized arrays have been ruled out, we can check this by just<br>
> > -       * making sure the sizes are equal.<br>
> > -       */<br>
> > -      if (consumer->array_size != producer->array_size)<br>
> > +      consumer_instance_type = consumer->var->type;<br>
> > +   }<br>
> > +<br>
> > +   /* If a block is an array then it must match across shaders.<br>
> > +    * Since unsized arrays have been ruled out, we can check this by just<br>
> > +    * making sure the types are equal.<br>
> > +    */<br>
> > +   if ((consumer->instance_name != NULL &&<br>
> > +        consumer_instance_type->is_array()) ||<br>
> > +       (producer->instance_name != NULL &&<br>
> > +        producer->var->type->is_array())) {<br>
> > +      if (consumer_instance_type != producer->var->type)<br>
> >           return false;<br>
> >     }<br>
> > +<br>
> >     return true;<br>
> >  }<br>
> >  <br>
> > @@ -298,7 +291,8 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog,<br>
> >               */<br>
> >              definitions->store(def);<br>
> >           } else if (!intrastage_match(prev_def, &def,<br>
> > -                                      (ir_variable_mode) var->data.mode)) {<br>
> > +                                      (ir_variable_mode) var->data.mode,<br>
> > +                                      prog)) {<br>
> >              linker_error(prog, "definitions of interface block `%s' do not"<br>
> >                           " match\n", iface_type->name);<br>
> >              return;<br>
> > @@ -374,7 +368,7 @@ validate_interstage_uniform_blocks(struct gl_shader_program *prog,<br>
> >               * uniform matchin rules (for uniforms, it is as though all<br>
> >               * shaders are in the same shader stage).<br>
> >               */<br>
> > -            if (!intrastage_match(old_def, &new_def, ir_var_uniform)) {<br>
> > +            if (!intrastage_match(old_def, &new_def, ir_var_uniform, prog)) {<br>
> >                 linker_error(prog, "definitions of interface block `%s' do not "<br>
> >                              "match\n", var->get_interface_type()->name);<br>
> >                 return;<br>
> > -- <br>
> > 2.1.0<br>
> ><br>
> > _______________________________________________<br>
> > mesa-dev mailing list<br>
> > <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> > <a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a></p>