[Mesa-dev] [PATCH 09/20] mesa: Add a concept of an array format

Iago Toral itoral at igalia.com
Tue Nov 18 23:18:33 PST 2014


On Tue, 2014-11-18 at 10:46 -0800, Jason Ekstrand wrote:
> 
> 
> On Tue, Nov 18, 2014 at 12:43 AM, Iago Toral Quiroga
> <itoral at igalia.com> 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.
> 
> 
> I'm not terribly surprised, I never got a chance to test that function
> before I handed it off to you.  I'm curious how you found it though,
> given that it's only run on big endian architectures.  Maybe it was
> just obviously wrong.  (silly me).  In any case, the new version looks
> good to me.

I noticed that because at some point I thought I needed to flip the
channels for GL_UNSIGNED_INT_8_8_8_8 in certain cases (I was wrong about
that in the end, but that drove me to look into it), and when I looked
at the function it was pretty obvious that it was not doing what it was
expected.

Iago

> --Jason
> 
>  
>         ---
>          src/mesa/main/format_info.py | 41
>         ++++++++++++++++++++++++++++++++
>          src/mesa/main/formats.c      | 56
>         +++++++++++++++++++++++++++++++++++++++++++-
>          src/mesa/main/formats.h      | 55
>         +++++++++++++++++++++++++++++++++++++++++++
>          3 files changed, 151 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");
>         +}
>         +
>         +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;
>          }
>         
>         -
>          /**
>           * 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..7642875 100644
>         --- a/src/mesa/main/formats.h
>         +++ b/src/mesa/main/formats.h
>         @@ -81,6 +81,55 @@ 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,
>         +
>         +   MESA_ARRAY_FORMAT_TYPE_IS_SIGNED = 0x4,
>         +   MESA_ARRAY_FORMAT_TYPE_IS_FLOAT = 0x8,
>         +};
>         +
>         +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 */
>         +   };
>         +   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;
>         +   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)
>         +
>          /**
>           * Mesa texture/renderbuffer image formats.
>           */
>         @@ -469,6 +518,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);
>         
>         --
>         1.9.1
>         
>         _______________________________________________
>         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