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"); +} + +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..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 + +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) + +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); -- 1.9.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev