On Wed, Dec 3, 2014 at 2:52 PM, Ian Romanick <i...@freedesktop.org> wrote:
> On 12/01/2014 03:04 AM, Iago Toral Quiroga wrote: > > From: Jason Ekstrand <jason.ekstr...@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 <ito...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev