[Mesa-dev] [PATCH v3 10/24] main: Add a concept of an array format
Jason Ekstrand
jason at jlekstrand.net
Fri Dec 12 07:32:46 PST 2014
On Dec 11, 2014 11:46 PM, "Iago Toral" <itoral at igalia.com> wrote:
>
> On Fri, 2014-12-12 at 08:21 +0100, Iago Toral wrote:
> > On Thu, 2014-12-11 at 11:24 -0800, Jason Ekstrand wrote:
> > >
> > >
> > > On Tue, Dec 9, 2014 at 4:06 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.
> > > Whie 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>:
> > > - Implement mesa_array_format as a plain bitfiled uint32_t
> > > type instead of
> > > using a struct inside a union to access the various
> > > components packed in
> > > it. This is necessary to support bigendian properly, as
> > > pointed out by
> > > Ian.
> > > - Squashed: Make float types normalized
> > > ---
> > > src/mesa/main/format_info.py | 16 +++++
> > > src/mesa/main/formats.c | 57 ++++++++++++++++++
> > > src/mesa/main/formats.h | 136
> > > ++++++++++++++++++++++++++++++++++++++++++-
> > > 3 files changed, 208 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/src/mesa/main/format_info.py
> > > b/src/mesa/main/format_info.py
> > > index 7424fe0..fe2063d 100644
> > > --- a/src/mesa/main/format_info.py
> > > +++ b/src/mesa/main/format_info.py
> > > @@ -192,6 +192,22 @@ for fmat in formats:
> > >
> > > int(fmat.block_size() / 8))
> > >
> > > print ' {{ {0} }},'.format(', '.join(map(str,
> > > fmat.swizzle)))
> > > + if fmat.is_array():
> > > + chan = fmat.array_element()
> > > + norm = chan.norm or chan.type == parser.FLOAT
> > > + print ' MESA_ARRAY_FORMAT({0}),'.format(',
> > > '.join([
> > > + str(chan.size / 8),
> > > + str(int(chan.sign)),
> > > + str(int(chan.type == parser.FLOAT)),
> > > + str(int(norm)),
> > > + str(len(fmat.channels)),
> > > + str(fmat.swizzle[0]),
> > > + str(fmat.swizzle[1]),
> > > + str(fmat.swizzle[2]),
> > > + str(fmat.swizzle[3]),
> > > + ]))
> > > + else:
> > > + print ' 0,'
> > > print ' },'
> > >
> > > print '};'
> > > diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
> > > index 676ac27..1259892 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,62 @@ _mesa_get_format_swizzle(mesa_format
> > > format, uint8_t swizzle_out[4])
> > > memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle));
> > > }
> > >
> > > +mesa_array_format
> > > +_mesa_array_format_flip_channels(mesa_array_format format)
> > > +{
> > > + int num_channels;
> > > + uint8_t swizzle[4];
> > > +
> > > + num_channels =
> > > _mesa_array_format_get_num_channels(format);
> > > + _mesa_array_format_get_swizzle(format, swizzle);
> > > +
> > > + if (num_channels == 1)
> > > + return format;
> > > +
> > > + if (num_channels == 2) {
> > > + _mesa_array_format_set_swizzle(&format, swizzle[1],
> > > swizzle[0],
> > > + swizzle[2], swizzle[3]);
> > > + return format;
> > > + }
> > > +
> > > + if (num_channels == 4) {
> > > + _mesa_array_format_set_swizzle(&format, swizzle[3],
> > > swizzle[2],
> > > + swizzle[1], swizzle[0]);
> > > + return format;
> > > + }
> > > +
> > > + unreachable("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;
> > > + else
> > > + return
> > > _mesa_array_format_flip_channels(info->ArrayFormat);
> > > +}
> > > +
> > > +mesa_format
> > > +_mesa_format_from_array_format(uint32_t array_format)
> > > +{
> > > + mesa_array_format af;
> > > + unsigned f;
> > > +
> > > + assert(_mesa_format_is_mesa_array_format(array_format));
> > > +
> > > + if (_mesa_little_endian())
> > > + af = array_format;
> > > + else
> > > + af = _mesa_array_format_flip_channels(array_format);
> > > +
> > > + for (f = 1; f < MESA_FORMAT_COUNT; ++f)
> > > + if (_mesa_get_format_info(f)->ArrayFormat == af)
> > > + return f;
> > > +
> > > + return MESA_FORMAT_NONE;
> > > +}
> > >
> > > /** Is the given format a compressed format? */
> > > GLboolean
> > > diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
> > > index 213ab56..746a92f 100644
> > > --- a/src/mesa/main/formats.h
> > > +++ b/src/mesa/main/formats.h
> > > @@ -37,7 +37,6 @@
> > > #include <stdbool.h>
> > > #include <stdint.h>
> > >
> > > -
> > > #ifdef __cplusplus
> > > extern "C" {
> > > #endif
> > > @@ -82,6 +81,132 @@ enum {
> > > };
> > >
> > > /**
> > > + * An uint32_t that encodes the information necessary to
> > > represent an
> > > + * array format
> > > + */
> > > +typedef uint32_t mesa_array_format;
> > > +
> > > +/**
> > > + * Encoding for valid array format data types
> > > + */
> > > +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,
> > > +};
> > > +
> > > +/**
> > > + * An enum useful to encode/decode information stored in a
> > > mesa_array_format
> > > + */
> > > +enum {
> > > + MESA_ARRAY_FORMAT_TYPE_IS_SIGNED = 0x4,
> > > + MESA_ARRAY_FORMAT_TYPE_IS_FLOAT = 0x8,
> > > + MESA_ARRAY_FORMAT_TYPE_NORMALIZED = 0x10,
> > > + MESA_ARRAY_FORMAT_DATATYPE_MASK = 0xf,
> > > + MESA_ARRAY_FORMAT_TYPE_MASK = 0x1f,
> > > + MESA_ARRAY_FORMAT_TYPE_SIZE_MASK = 0x3,
> > > + MESA_ARRAY_FORMAT_NUM_CHANS_MASK = 0xe0,
> > > + MESA_ARRAY_FORMAT_SWIZZLE_X_MASK = 0x00700,
> > > + MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK = 0x03800,
> > > + MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK = 0x1c000,
> > > + MESA_ARRAY_FORMAT_SWIZZLE_W_MASK = 0xe0000,
> > > + MESA_ARRAY_FORMAT_BIT = 0x80000000
> > > +};
> > > +
> > > +#define MESA_ARRAY_FORMAT(SIZE, SIGNED, IS_FLOAT, NORM,
> > > NUM_CHANS, \
> > > + SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W) (
> > > \
> > > + (((SIZE >> 1) ) & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK) |
> > > \
> > > + (((SIGNED) << 2 ) & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) |
> > > \
> > > + (((IS_FLOAT) << 3 ) & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT)
> > > | \
> > > + (((NORM) << 4 ) & MESA_ARRAY_FORMAT_TYPE_NORMALIZED)
> > > | \
> > > + (((NUM_CHANS) << 5 ) & MESA_ARRAY_FORMAT_NUM_CHANS_MASK) |
> > > \
> > > + (((SWIZZLE_X) << 8 ) & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) |
> > > \
> > > + (((SWIZZLE_Y) << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) |
> > > \
> > > + (((SWIZZLE_Z) << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) |
> > > \
> > > + (((SWIZZLE_W) << 17) & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK) |
> > > \
> > > + MESA_ARRAY_FORMAT_BIT)
> > > +
> > > +/**
> > > + * Various helpers to access the data encoded in a
> > > mesa_array_format
> > > + */
> > > +static inline bool
> > > +_mesa_array_format_is_signed(mesa_array_format f)
> > > +{
> > > + return (f & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) > 0;
> > > +}
> > > +
> > > +static inline bool
> > > +_mesa_array_format_is_float(mesa_array_format f)
> > > +{
> > > + return (f & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) > 0;
> > > +}
> > > +
> > > +static inline bool
> > > +_mesa_array_format_is_normalized(mesa_array_format f)
> > > +{
> > > + return (f & MESA_ARRAY_FORMAT_TYPE_NORMALIZED) > 0;
> > > +}
> > >
> > >
> > > Any particular reason why you do "> 0" instead of "!= 0"? I don't
> > > care that much. Just curious
> >
> > mesa_array_format is an uint32_t so this can't be < 0. Anyway, using !=
> > 0 may be more clear so I'll change that.
>
> Jason, since this is the only comment you had for this patch, should I
> assume that it has your reviewed-by?
Go ahead
>
> Iago
>
> > >
> > >
> > > +
> > > +static inline enum mesa_array_format_datatype
> > > +_mesa_array_format_get_datatype(mesa_array_format f)
> > > +{
> > > + return (enum mesa_array_format_datatype)
> > > + (f & MESA_ARRAY_FORMAT_DATATYPE_MASK);
> > > +}
> > > +
> > > +static inline int
> > > +_mesa_array_format_datatype_get_size(enum
> > > mesa_array_format_datatype type)
> > > +{
> > > + return 1 << (type & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK);
> > > +}
> > > +
> > > +static inline int
> > > +_mesa_array_format_get_type_size(mesa_array_format f)
> > > +{
> > > + return 1 << (f & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK);
> > > +}
> > > +
> > > +static inline int
> > > +_mesa_array_format_get_num_channels(mesa_array_format f)
> > > +{
> > > + return (f & MESA_ARRAY_FORMAT_NUM_CHANS_MASK) >> 5;
> > > +}
> > > +
> > > +static inline void
> > > +_mesa_array_format_get_swizzle(mesa_array_format f, uint8_t
> > > *swizzle)
> > > +{
> > > + swizzle[0] = (f & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) >> 8;
> > > + swizzle[1] = (f & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) >> 11;
> > > + swizzle[2] = (f & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) >> 14;
> > > + swizzle[3] = (f & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK) >> 17;
> > > +}
> > > +
> > > +static inline void
> > > +_mesa_array_format_set_swizzle(mesa_array_format *f,
> > > + int32_t x, int32_t y, int32_t
> > > z, int32_t w)
> > > +{
> > > + *f |= ((x << 8 ) & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) |
> > > + ((y << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) |
> > > + ((z << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) |
> > > + ((w << 17) & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK);
> > > +}
> > > +
> > > +/**
> > > + * A helper to know if the format stored in a uint32_t is a
> > > mesa_format
> > > + * or a mesa_array_format
> > > + */
> > > +static inline bool
> > > +_mesa_format_is_mesa_array_format(uint32_t f)
> > > +{
> > > + return (f & MESA_ARRAY_FORMAT_BIT) > 0;
> > > +}
> > > +
> > > +/**
> > > * Mesa texture/renderbuffer image formats.
> > > */
> > > typedef enum
> > > @@ -466,9 +591,18 @@ _mesa_get_format_base_format(mesa_format
> > > format);
> > > extern void
> > > _mesa_get_format_block_size(mesa_format format, GLuint *bw,
> > > GLuint *bh);
> > >
> > > +extern mesa_array_format
> > > +_mesa_array_format_flip_channels(mesa_array_format format);
> > > +
> > > 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
> > >
> > >
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20141212/fb2a77fa/attachment-0001.html>
More information about the mesa-dev
mailing list