[Mesa-dev] [PATCH 09/20] mesa: Add a concept of an array format
Iago Toral
itoral at igalia.com
Tue Nov 18 23:18:33 PST 2014
On Tue, 2014-11-18 at 10:46 -0800, Jason Ekstrand wrote:
>
>
> On Tue, Nov 18, 2014 at 12:43 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.
> 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.
>
>
> I'm not terribly surprised, I never got a chance to test that function
> before I handed it off to you. I'm curious how you found it though,
> given that it's only run on big endian architectures. Maybe it was
> just obviously wrong. (silly me). In any case, the new version looks
> good to me.
I noticed that because at some point I thought I needed to flip the
channels for GL_UNSIGNED_INT_8_8_8_8 in certain cases (I was wrong about
that in the end, but that drove me to look into it), and when I looked
at the function it was pretty obvious that it was not doing what it was
expected.
Iago
> --Jason
>
>
> ---
> src/mesa/main/format_info.py | 41
> ++++++++++++++++++++++++++++++++
> src/mesa/main/formats.c | 56
> +++++++++++++++++++++++++++++++++++++++++++-
> src/mesa/main/formats.h | 55
> +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 151 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..7642875 100644
> --- a/src/mesa/main/formats.h
> +++ b/src/mesa/main/formats.h
> @@ -81,6 +81,55 @@ 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,
> +
> + MESA_ARRAY_FORMAT_TYPE_IS_SIGNED = 0x4,
> + MESA_ARRAY_FORMAT_TYPE_IS_FLOAT = 0x8,
> +};
> +
> +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)
> +
> /**
> * Mesa texture/renderbuffer image formats.
> */
> @@ -469,6 +518,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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
>
More information about the mesa-dev
mailing list