<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 3, 2014 at 2:52 PM, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 12/01/2014 03:04 AM, Iago Toral Quiroga wrote:<br>
> From: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br>
><br>
> An array format is a 32-bit integer format identifier that can represent<br>
> any format that can be represented as an array of standard GL datatypes.<br>
> While the MESA_FORMAT enums provide several of these, they don't account<br>
> for all of them.<br>
><br>
> v2 by Iago Toral Quiroga <<a href="mailto:itoral@igalia.com">itoral@igalia.com</a>>:<br>
> - Set pad to 0 and array_format_bit to 1 for all mesa array formats.<br>
> - Fix array_format_flip_channels, since it was not doing what was expected.<br>
> ---<br>
> src/mesa/main/format_info.py | 41 +++++++++++++++++++++++++++++<br>
> src/mesa/main/formats.c | 56 ++++++++++++++++++++++++++++++++++++++-<br>
> src/mesa/main/formats.h | 62 ++++++++++++++++++++++++++++++++++++++++++++<br>
> 3 files changed, 158 insertions(+), 1 deletion(-)<br>
><br>
> diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py<br>
> index 7424fe0..315767d 100644<br>
> --- a/src/mesa/main/format_info.py<br>
> +++ b/src/mesa/main/format_info.py<br>
> @@ -98,6 +98,32 @@ def get_gl_data_type(fmat):<br>
> else:<br>
> assert False<br>
><br>
> +def get_array_format_datatype(chan):<br>
> + if chan.type == parser.FLOAT:<br>
> + if chan.size == 16:<br>
> + return 'MESA_ARRAY_FORMAT_TYPE_HALF'<br>
> + elif chan.size == 32:<br>
> + return 'MESA_ARRAY_FORMAT_TYPE_FLOAT'<br>
> + else:<br>
> + assert False<br>
> + elif chan.type in (parser.SIGNED, parser.UNSIGNED):<br>
> + datatype = 'MESA_ARRAY_FORMAT_TYPE_'<br>
> + if chan.type == parser.UNSIGNED:<br>
> + datatype += 'U'<br>
> +<br>
> + if chan.size == 8:<br>
> + datatype += 'BYTE'<br>
> + elif chan.size == 16:<br>
> + datatype += 'SHORT'<br>
> + elif chan.size == 32:<br>
> + datatype += 'INT'<br>
> + else:<br>
> + print chan.size<br>
> + assert False<br>
> + return datatype<br>
> + else:<br>
> + assert False<br>
> +<br>
> def get_mesa_layout(fmat):<br>
> if fmat.layout == 'array':<br>
> return 'MESA_FORMAT_LAYOUT_ARRAY'<br>
> @@ -192,6 +218,21 @@ for fmat in formats:<br>
> int(fmat.block_size() / 8))<br>
><br>
> print ' {{ {0} }},'.format(', '.join(map(str, fmat.swizzle)))<br>
> + if fmat.is_array() and fmat.colorspace in ('rgb', 'srgb'):<br>
> + chan = fmat.array_element()<br>
> + print ' {{{{ {0} }}}},'.format(', '.join([<br>
> + get_array_format_datatype(chan),<br>
> + str(int(chan.norm)),<br>
> + str(len(fmat.channels)),<br>
> + str(fmat.swizzle[0]),<br>
> + str(fmat.swizzle[1]),<br>
> + str(fmat.swizzle[2]),<br>
> + str(fmat.swizzle[3]),<br>
> + str(int(0)),<br>
> + str(int(1))<br>
> + ]))<br>
> + else:<br>
> + print ' {{ MESA_ARRAY_FORMAT_TYPE_UBYTE, 0, 0, 0, 0, 0, 0, 0, 0 }},'<br>
> print ' },'<br>
><br>
> print '};'<br>
> diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c<br>
> index 7ec0507..f86925e 100644<br>
> --- a/src/mesa/main/formats.c<br>
> +++ b/src/mesa/main/formats.c<br>
> @@ -71,6 +71,7 @@ struct gl_format_info<br>
> GLubyte BytesPerBlock;<br>
><br>
> uint8_t Swizzle[4];<br>
> + mesa_array_format ArrayFormat;<br>
> };<br>
><br>
> #include "format_info.c"<br>
> @@ -269,6 +270,60 @@ _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4])<br>
> memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle));<br>
> }<br>
><br>
> +static mesa_array_format<br>
> +array_format_flip_channels(mesa_array_format format)<br>
> +{<br>
> + if (format.num_channels == 1)<br>
> + return format;<br>
> +<br>
> + if (format.num_channels == 2) {<br>
> + int tmp = format.swizzle_x;<br>
> + format.swizzle_x = format.swizzle_y;<br>
> + format.swizzle_y = tmp;<br>
> + return format;<br>
> + }<br>
> +<br>
> + if (format.num_channels == 4) {<br>
> + int tmp = format.swizzle_x;<br>
> + format.swizzle_x = format.swizzle_w;<br>
> + format.swizzle_w = tmp;<br>
> + tmp = format.swizzle_y;<br>
> + format.swizzle_y = format.swizzle_z;<br>
> + format.swizzle_z = tmp;<br>
> + return format;<br>
> + }<br>
> +<br>
> + assert(!"Invalid array format");<br>
<br>
</div></div>Use unreachable() to prevent warnings in non-debug builds.<br>
<div><div class="h5"><br>
> +}<br>
> +<br>
> +uint32_t<br>
> +_mesa_format_to_array_format(mesa_format format)<br>
> +{<br>
> + const struct gl_format_info *info = _mesa_get_format_info(format);<br>
> + if (_mesa_little_endian())<br>
> + return info->ArrayFormat.as_uint;<br>
> + else<br>
> + return array_format_flip_channels(info->ArrayFormat).as_uint;<br>
> +}<br>
> +<br>
> +mesa_format<br>
> +_mesa_format_from_array_format(uint32_t array_format)<br>
> +{<br>
> + mesa_array_format af;<br>
> + unsigned f;<br>
> +<br>
> + af.as_uint = array_format;<br>
> + af.pad = 0;<br>
> + if (!_mesa_little_endian())<br>
> + af = array_format_flip_channels(af);<br>
> +<br>
> + assert(af.array_format_bit);<br>
> + for (f = 1; f < MESA_FORMAT_COUNT; ++f)<br>
> + if (_mesa_get_format_info(f)->ArrayFormat.as_uint == af.as_uint)<br>
> + return f;<br>
> +<br>
> + return MESA_FORMAT_NONE;<br>
> +}<br>
><br>
> /** Is the given format a compressed format? */<br>
> GLboolean<br>
> @@ -278,7 +333,6 @@ _mesa_is_format_compressed(mesa_format format)<br>
> return info->BlockWidth > 1 || info->BlockHeight > 1;<br>
> }<br>
><br>
> -<br>
<br>
</div></div>Spurious whitespace change.<br>
<span class=""><br>
> /**<br>
> * Determine if the given format represents a packed depth/stencil buffer.<br>
> */<br>
> diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h<br>
> index 213ab56..8b62788 100644<br>
> --- a/src/mesa/main/formats.h<br>
> +++ b/src/mesa/main/formats.h<br>
> @@ -81,6 +81,62 @@ enum {<br>
> MESA_FORMAT_SWIZZLE_NONE = 6,<br>
> };<br>
><br>
> +enum mesa_array_format_datatype {<br>
> + MESA_ARRAY_FORMAT_TYPE_UBYTE = 0x0,<br>
> + MESA_ARRAY_FORMAT_TYPE_USHORT = 0x1,<br>
> + MESA_ARRAY_FORMAT_TYPE_UINT = 0x2,<br>
> + MESA_ARRAY_FORMAT_TYPE_BYTE = 0x4,<br>
> + MESA_ARRAY_FORMAT_TYPE_SHORT = 0x5,<br>
> + MESA_ARRAY_FORMAT_TYPE_INT = 0x6,<br>
> + MESA_ARRAY_FORMAT_TYPE_HALF = 0xd,<br>
> + MESA_ARRAY_FORMAT_TYPE_FLOAT = 0xe,<br>
> +};<br>
> +<br>
> +#define MESA_ARRAY_FORMAT_TYPE_IS_SIGNED 0x4<br>
> +#define MESA_ARRAY_FORMAT_TYPE_IS_FLOAT 0x8<br>
> +#define MESA_ARRAY_FORMAT_BIT 0x80000000<br>
<br>
</span>This...<br>
<span class=""><br>
> +<br>
> +typedef union {<br>
> + struct {<br>
> + enum mesa_array_format_datatype type:4;<br>
> + bool normalized:1;<br>
> + unsigned num_channels:3;<br>
> + unsigned swizzle_x:3;<br>
> + unsigned swizzle_y:3;<br>
> + unsigned swizzle_z:3;<br>
> + unsigned swizzle_w:3;<br>
> + unsigned pad:11;<br>
> + unsigned array_format_bit:1; /* Must always be 1 */<br>
<br>
</span>...and this are not correct on big-endian.<br></blockquote><div><br></div><div>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...<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
> + };<br>
> + uint32_t as_uint;<br>
> +} mesa_array_format;<br>
> +<br>
> +static const mesa_array_format _mesa_array_format_none = {{<br>
> + MESA_ARRAY_FORMAT_TYPE_UBYTE,<br>
> + 0, 0, 0, 0, 0, 0, 0, 0<br>
> +}};<br>
> +<br>
> +static inline unsigned<br>
> +_mesa_ilog2(unsigned x)<br>
> +{<br>
> + uint8_t i;<br>
<br>
</span>I'd either make this unsigned or uint_fast8_t... I'd bet that it doesn't<br>
make any difference.<br>
<div class="HOEnZb"><div class="h5"><br>
> + for (i = 1; i < 32; ++i)<br>
> + if (x <= (1u << i))<br>
> + return i;<br>
> + return 32;<br>
> +}<br>
> +<br>
> +#define MESA_ARRAY_FORMAT_TYPE(SIZE, SIGNED, IS_FLOAT, NORM) ( \<br>
> + ((_mesa_ilog2(SIZE)) & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK) | \<br>
> + (((SIGNED) << 2 ) & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) | \<br>
> + (((IS_FLOAT) << 3 ) & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT)<br>
> +<br>
> +static inline int<br>
> +_mesa_array_format_datatype_size(enum mesa_array_format_datatype type)<br>
> +{<br>
> + return 1 << (type & 0x3);<br>
> +}<br>
> +<br>
> /**<br>
> * Mesa texture/renderbuffer image formats.<br>
> */<br>
> @@ -469,6 +525,12 @@ _mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh);<br>
> extern void<br>
> _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]);<br>
><br>
> +extern uint32_t<br>
> +_mesa_format_to_array_format(mesa_format format);<br>
> +<br>
> +extern mesa_format<br>
> +_mesa_format_from_array_format(uint32_t array_format);<br>
> +<br>
> extern GLboolean<br>
> _mesa_is_format_compressed(mesa_format format);<br>
><br>
><br>
<br>
</div></div><div class="HOEnZb"><div class="h5">_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</div></div></blockquote></div><br></div></div>