[Mesa-dev] [PATCH v2 10/23] mesa: Add a concept of an array format

Jason Ekstrand jason at jlekstrand.net
Wed Dec 3 14:58:48 PST 2014


On Wed, Dec 3, 2014 at 2:52 PM, Ian Romanick <idr at freedesktop.org> wrote:

> On 12/01/2014 03:04 AM, Iago Toral Quiroga wrote:
> > From: Jason Ekstrand <jason.ekstrand at intel.com>
> >
> > An array format is a 32-bit integer format identifier that can represent
> > any format that can be represented as an array of standard GL datatypes.
> > While the MESA_FORMAT enums provide several of these, they don't account
> > for all of them.
> >
> > v2 by Iago Toral Quiroga <itoral at igalia.com>:
> > - Set pad to 0 and array_format_bit to 1 for all mesa array formats.
> > - Fix array_format_flip_channels, since it was not doing what was
> expected.
> > ---
> >  src/mesa/main/format_info.py | 41 +++++++++++++++++++++++++++++
> >  src/mesa/main/formats.c      | 56
> ++++++++++++++++++++++++++++++++++++++-
> >  src/mesa/main/formats.h      | 62
> ++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 158 insertions(+), 1 deletion(-)
> >
> > diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py
> > index 7424fe0..315767d 100644
> > --- a/src/mesa/main/format_info.py
> > +++ b/src/mesa/main/format_info.py
> > @@ -98,6 +98,32 @@ def get_gl_data_type(fmat):
> >     else:
> >        assert False
> >
> > +def get_array_format_datatype(chan):
> > +   if chan.type == parser.FLOAT:
> > +      if chan.size == 16:
> > +         return 'MESA_ARRAY_FORMAT_TYPE_HALF'
> > +      elif chan.size == 32:
> > +         return 'MESA_ARRAY_FORMAT_TYPE_FLOAT'
> > +      else:
> > +         assert False
> > +   elif chan.type in (parser.SIGNED, parser.UNSIGNED):
> > +      datatype = 'MESA_ARRAY_FORMAT_TYPE_'
> > +      if chan.type == parser.UNSIGNED:
> > +         datatype += 'U'
> > +
> > +      if chan.size == 8:
> > +         datatype += 'BYTE'
> > +      elif chan.size == 16:
> > +         datatype += 'SHORT'
> > +      elif chan.size == 32:
> > +         datatype += 'INT'
> > +      else:
> > +         print chan.size
> > +         assert False
> > +      return datatype
> > +   else:
> > +      assert False
> > +
> >  def get_mesa_layout(fmat):
> >     if fmat.layout == 'array':
> >        return 'MESA_FORMAT_LAYOUT_ARRAY'
> > @@ -192,6 +218,21 @@ for fmat in formats:
> >                                         int(fmat.block_size() / 8))
> >
> >     print '      {{ {0} }},'.format(', '.join(map(str, fmat.swizzle)))
> > +   if fmat.is_array() and fmat.colorspace in ('rgb', 'srgb'):
> > +      chan = fmat.array_element()
> > +      print '      {{{{ {0} }}}},'.format(', '.join([
> > +         get_array_format_datatype(chan),
> > +         str(int(chan.norm)),
> > +         str(len(fmat.channels)),
> > +         str(fmat.swizzle[0]),
> > +         str(fmat.swizzle[1]),
> > +         str(fmat.swizzle[2]),
> > +         str(fmat.swizzle[3]),
> > +         str(int(0)),
> > +         str(int(1))
> > +      ]))
> > +   else:
> > +      print '      {{ MESA_ARRAY_FORMAT_TYPE_UBYTE, 0, 0, 0, 0, 0, 0,
> 0, 0 }},'
> >     print '   },'
> >
> >  print '};'
> > diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
> > index 7ec0507..f86925e 100644
> > --- a/src/mesa/main/formats.c
> > +++ b/src/mesa/main/formats.c
> > @@ -71,6 +71,7 @@ struct gl_format_info
> >     GLubyte BytesPerBlock;
> >
> >     uint8_t Swizzle[4];
> > +   mesa_array_format ArrayFormat;
> >  };
> >
> >  #include "format_info.c"
> > @@ -269,6 +270,60 @@ _mesa_get_format_swizzle(mesa_format format,
> uint8_t swizzle_out[4])
> >     memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle));
> >  }
> >
> > +static mesa_array_format
> > +array_format_flip_channels(mesa_array_format format)
> > +{
> > +   if (format.num_channels == 1)
> > +      return format;
> > +
> > +   if (format.num_channels == 2) {
> > +      int tmp = format.swizzle_x;
> > +      format.swizzle_x = format.swizzle_y;
> > +      format.swizzle_y = tmp;
> > +      return format;
> > +   }
> > +
> > +   if (format.num_channels == 4) {
> > +      int tmp = format.swizzle_x;
> > +      format.swizzle_x = format.swizzle_w;
> > +      format.swizzle_w = tmp;
> > +      tmp = format.swizzle_y;
> > +      format.swizzle_y = format.swizzle_z;
> > +      format.swizzle_z = tmp;
> > +      return format;
> > +   }
> > +
> > +   assert(!"Invalid array format");
>
> Use unreachable() to prevent warnings in non-debug builds.
>
> > +}
> > +
> > +uint32_t
> > +_mesa_format_to_array_format(mesa_format format)
> > +{
> > +   const struct gl_format_info *info = _mesa_get_format_info(format);
> > +   if (_mesa_little_endian())
> > +      return info->ArrayFormat.as_uint;
> > +   else
> > +      return array_format_flip_channels(info->ArrayFormat).as_uint;
> > +}
> > +
> > +mesa_format
> > +_mesa_format_from_array_format(uint32_t array_format)
> > +{
> > +   mesa_array_format af;
> > +   unsigned f;
> > +
> > +   af.as_uint = array_format;
> > +   af.pad = 0;
> > +   if (!_mesa_little_endian())
> > +      af = array_format_flip_channels(af);
> > +
> > +   assert(af.array_format_bit);
> > +   for (f = 1; f < MESA_FORMAT_COUNT; ++f)
> > +      if (_mesa_get_format_info(f)->ArrayFormat.as_uint == af.as_uint)
> > +         return f;
> > +
> > +   return MESA_FORMAT_NONE;
> > +}
> >
> >  /** Is the given format a compressed format? */
> >  GLboolean
> > @@ -278,7 +333,6 @@ _mesa_is_format_compressed(mesa_format format)
> >     return info->BlockWidth > 1 || info->BlockHeight > 1;
> >  }
> >
> > -
>
> Spurious whitespace change.
>
> >  /**
> >   * Determine if the given format represents a packed depth/stencil
> buffer.
> >   */
> > diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
> > index 213ab56..8b62788 100644
> > --- a/src/mesa/main/formats.h
> > +++ b/src/mesa/main/formats.h
> > @@ -81,6 +81,62 @@ enum {
> >     MESA_FORMAT_SWIZZLE_NONE = 6,
> >  };
> >
> > +enum mesa_array_format_datatype {
> > +   MESA_ARRAY_FORMAT_TYPE_UBYTE = 0x0,
> > +   MESA_ARRAY_FORMAT_TYPE_USHORT = 0x1,
> > +   MESA_ARRAY_FORMAT_TYPE_UINT = 0x2,
> > +   MESA_ARRAY_FORMAT_TYPE_BYTE = 0x4,
> > +   MESA_ARRAY_FORMAT_TYPE_SHORT = 0x5,
> > +   MESA_ARRAY_FORMAT_TYPE_INT = 0x6,
> > +   MESA_ARRAY_FORMAT_TYPE_HALF = 0xd,
> > +   MESA_ARRAY_FORMAT_TYPE_FLOAT = 0xe,
> > +};
> > +
> > +#define MESA_ARRAY_FORMAT_TYPE_IS_SIGNED 0x4
> > +#define MESA_ARRAY_FORMAT_TYPE_IS_FLOAT 0x8
> > +#define MESA_ARRAY_FORMAT_BIT 0x80000000
>
> This...
>
> > +
> > +typedef union {
> > +   struct {
> > +      enum mesa_array_format_datatype type:4;
> > +      bool normalized:1;
> > +      unsigned num_channels:3;
> > +      unsigned swizzle_x:3;
> > +      unsigned swizzle_y:3;
> > +      unsigned swizzle_z:3;
> > +      unsigned swizzle_w:3;
> > +      unsigned pad:11;
> > +      unsigned array_format_bit:1; /* Must always be 1 */
>
> ...and this are not correct on big-endian.
>

Bah!  I originally did this as a bitfield in a uint32_t and then decided
that the union was easier.  Probably best to go back to the bitfield...


>
> > +   };
> > +   uint32_t as_uint;
> > +} mesa_array_format;
> > +
> > +static const mesa_array_format _mesa_array_format_none = {{
> > +   MESA_ARRAY_FORMAT_TYPE_UBYTE,
> > +   0, 0, 0, 0, 0, 0, 0, 0
> > +}};
> > +
> > +static inline unsigned
> > +_mesa_ilog2(unsigned x)
> > +{
> > +   uint8_t i;
>
> I'd either make this unsigned or uint_fast8_t... I'd bet that it doesn't
> make any difference.
>
> > +   for (i = 1; i < 32; ++i)
> > +      if (x <= (1u << i))
> > +         return i;
> > +   return 32;
> > +}
> > +
> > +#define MESA_ARRAY_FORMAT_TYPE(SIZE, SIGNED, IS_FLOAT, NORM) (     \
> > +   ((_mesa_ilog2(SIZE)) & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK) |      \
> > +   (((SIGNED)    << 2 ) & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) |      \
> > +   (((IS_FLOAT)  << 3 ) & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT)
> > +
> > +static inline int
> > +_mesa_array_format_datatype_size(enum mesa_array_format_datatype type)
> > +{
> > +   return 1 << (type & 0x3);
> > +}
> > +
> >  /**
> >   * Mesa texture/renderbuffer image formats.
> >   */
> > @@ -469,6 +525,12 @@ _mesa_get_format_block_size(mesa_format format,
> GLuint *bw, GLuint *bh);
> >  extern void
> >  _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]);
> >
> > +extern uint32_t
> > +_mesa_format_to_array_format(mesa_format format);
> > +
> > +extern mesa_format
> > +_mesa_format_from_array_format(uint32_t array_format);
> > +
> >  extern GLboolean
> >  _mesa_is_format_compressed(mesa_format format);
> >
> >
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20141203/8483dfc4/attachment.html>


More information about the mesa-dev mailing list