[Mesa-dev] [PATCH 15/28] glsl: add support for packing varyings with explicit locations

Timothy Arceri timothy.arceri at collabora.com
Wed Jan 20 13:53:57 PST 2016


On Wed, 2016-01-20 at 09:32 -0800, Anuj Phogat wrote:
> On Mon, Dec 28, 2015 at 9:00 PM, Timothy Arceri
> <timothy.arceri at collabora.com> wrote:
> > ---
> >  src/glsl/lower_packed_varyings.cpp | 45
> > +++++++++++++++++++++++++++-----------
> >  1 file changed, 32 insertions(+), 13 deletions(-)
> > 
> > diff --git a/src/glsl/lower_packed_varyings.cpp
> > b/src/glsl/lower_packed_varyings.cpp
> > index d91aa22..2899846 100644
> > --- a/src/glsl/lower_packed_varyings.cpp
> > +++ b/src/glsl/lower_packed_varyings.cpp
> > @@ -178,11 +178,13 @@ private:
> >     void bitwise_assign_unpack(ir_rvalue *lhs, ir_rvalue *rhs);
> >     unsigned lower_rvalue(ir_rvalue *rvalue, unsigned
> > fine_location,
> >                           ir_variable *unpacked_var, const char
> > *name,
> > -                         bool gs_input_toplevel, unsigned
> > vertex_index);
> > +                         bool gs_input_toplevel, unsigned
> > vertex_index,
> > +                         bool explicit_location);
> >     unsigned lower_arraylike(ir_rvalue *rvalue, unsigned
> > array_size,
> >                              unsigned fine_location,
> >                              ir_variable *unpacked_var, const char
> > *name,
> > -                            bool gs_input_toplevel, unsigned
> > vertex_index);
> > +                            bool gs_input_toplevel, unsigned
> > vertex_index,
> > +                            bool explicit_location);
> >     ir_dereference *get_packed_varying_deref(unsigned location,
> >                                              ir_variable
> > *unpacked_var,
> >                                              const char *name,
> > @@ -294,7 +296,8 @@ lower_packed_varyings_visitor::run(struct
> > gl_shader *shader)
> > 
> >        /* Recursively pack or unpack it. */
> >        this->lower_rvalue(deref, var->data.location * 4 + var
> > ->data.location_frac, var,
> > -                         var->name, this->gs_input_vertices != 0,
> > 0);
> > +                         var->name, this->gs_input_vertices != 0,
> > 0,
> > +                         var->data.explicit_location);
> >     }
> >  }
> > 
> > @@ -426,7 +429,8 @@
> > lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
> >                                              ir_variable
> > *unpacked_var,
> >                                              const char *name,
> >                                              bool
> > gs_input_toplevel,
> > -                                            unsigned vertex_index)
> > +                                            unsigned vertex_index,
> > +                                            bool
> > explicit_location)
> >  {
> >     unsigned dmul = rvalue->type->is_double() ? 2 : 1;
> >     /* When gs_input_toplevel is set, we should be looking at a
> > geometry shader
> > @@ -445,7 +449,7 @@
> > lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
> >              = ralloc_asprintf(this->mem_ctx, "%s.%s", name,
> > field_name);
> >           fine_location = this->lower_rvalue(dereference_record,
> > fine_location,
> >                                              unpacked_var,
> > deref_name, false,
> > -                                            vertex_index);
> > +                                            vertex_index,
> > explicit_location);
> >        }
> >        return fine_location;
> >     } else if (rvalue->type->is_array()) {
> > @@ -454,14 +458,15 @@
> > lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
> >         */
> >        return this->lower_arraylike(rvalue, rvalue->type
> > ->array_size(),
> >                                     fine_location, unpacked_var,
> > name,
> > -                                   gs_input_toplevel,
> > vertex_index);
> > +                                   gs_input_toplevel,
> > vertex_index,
> > +                                   explicit_location);
> >     } else if (rvalue->type->is_matrix()) {
> >        /* Matrices are packed/unpacked by considering each column
> > vector in
> >         * sequence.
> >         */
> >        return this->lower_arraylike(rvalue, rvalue->type
> > ->matrix_columns,
> >                                     fine_location, unpacked_var,
> > name,
> > -                                   false, vertex_index);
> > +                                   false, vertex_index,
> > explicit_location);
> >     } else if (rvalue->type->vector_elements * dmul +
> >                fine_location % 4 > 4) {
> >        /* This vector is going to be "double parked" across two
> > varying slots,
> > @@ -502,12 +507,13 @@
> > lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
> >        if (left_components)
> >           fine_location = this->lower_rvalue(left_swizzle,
> > fine_location,
> >                                              unpacked_var,
> > left_name, false,
> > -                                            vertex_index);
> > +                                            vertex_index,
> > explicit_location);
> >        else
> >           /* Top up the fine location to the next slot */
> >           fine_location++;
> >        return this->lower_rvalue(right_swizzle, fine_location,
> > unpacked_var,
> > -                                right_name, false, vertex_index);
> > +                                right_name, false, vertex_index,
> > +                                explicit_location);
> >     } else {
> >        /* No special handling is necessary; pack the rvalue into
> > the
> >         * varying.
> > @@ -528,7 +534,17 @@
> > lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
> >        } else {
> >           this->bitwise_assign_unpack(rvalue, swizzle);
> >        }
> > -      return fine_location + components;
> > +
> > +      /* Explicitly packed components are packed by interleaving
> > arrays, so
> > +       * simply bump the location by 4 to increment the location
> > to the next
> > +       * element.
> > +       *
> > +       * Otherwise we pack arrays elements end to end.
> > +       */
> Can you help me understand this comment using an example?

Sure. The existing packing for varyings with implicit locations works
by packing varyings one after the other end to end including arrays.
This means fine_location is incremented by the component size of the
varying element we just packed and the next element will be placed at
the end of this element.

So if we packed a vec3 array starting at component 0 the next element
will be packed in the same location starting at component 3, then the
next element will be in the following location at component 2, etc.

For varyings with explicit locations/components the rules are
different. As we specifiy the components where the elements should be
stored we just need to bump fine_location by 4 to end up at the same
component in the next location.

>From the ARB_enhanced_layouts spec:

       Further, an array of vec3 and an array of float can be stored 
       interleaved, using the following.

          // consumes W component of 32 vectors
          layout(location = 0, component = 3) in float robin[32];

          // consume X/Y/Z components of 32 vectors
          layout(location = 0) in vec3 batman[32];





> 
> > +      if (explicit_location) {
> > +         return fine_location + 4;
> > +      } else
> > +         return fine_location + components;
> >     }
> >  }
> > 
> > @@ -554,7 +570,8 @@
> > lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue,
> >                                                 ir_variable
> > *unpacked_var,
> >                                                 const char *name,
> >                                                 bool
> > gs_input_toplevel,
> > -                                               unsigned
> > vertex_index)
> > +                                               unsigned
> > vertex_index,
> > +                                               bool
> > explicit_location)
> >  {
> >     for (unsigned i = 0; i < array_size; i++) {
> >        if (i != 0)
> > @@ -568,14 +585,16 @@
> > lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue,
> >            * are at the same location, but with a different vertex
> > index.
> >            */
> >           (void) this->lower_rvalue(dereference_array,
> > fine_location,
> > -                                   unpacked_var, name, false, i);
> > +                                   unpacked_var, name, false, i,
> > +                                   explicit_location);
> >        } else {
> >           char *subscripted_name
> >              = ralloc_asprintf(this->mem_ctx, "%s[%d]", name, i);
> > +
> >           fine_location =
> >              this->lower_rvalue(dereference_array, fine_location,
> >                                 unpacked_var, subscripted_name,
> > -                               false, vertex_index);
> > +                               false, vertex_index,
> > explicit_location);
> >        }
> >     }
> >     return fine_location;
> > --
> > 2.4.3
> > 
> > _______________________________________________
> > mesa-dev mailing list
> > mesa-dev at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list