[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