[Mesa-dev] [PATCH 16/20] mesa/formats: add new mesa formats and their pack/unpack functions.
Samuel Iglesias Gonsálvez
siglesias at igalia.com
Thu Nov 20 04:19:11 PST 2014
On Tue, 2014-11-18 at 11:50 -0800, Jason Ekstrand wrote:
>
>
> On Tue, Nov 18, 2014 at 12:44 AM, Iago Toral Quiroga
> <itoral at igalia.com> wrote:
> From: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
>
> This will be used to refactor code in pack.c and support
> conversion
> to/from these types in a master convert function that will be
> added
> later.
>
> Signed-off-by: Samuel Iglesias Gonsalvez
> <siglesias at igalia.com>
> ---
> src/mesa/main/format_pack.c.mako | 36 ++++++++++++-
> src/mesa/main/format_unpack.c.mako | 35 ++++++++++++-
> src/mesa/main/formats.c | 104
> +++++++++++++++++++++++++++++++++++++
> src/mesa/main/formats.csv | 13 +++++
> src/mesa/main/formats.h | 15 ++++++
> src/mesa/swrast/s_texfetch.c | 13 +++++
> 6 files changed, 212 insertions(+), 4 deletions(-)
>
> diff --git a/src/mesa/main/format_pack.c.mako
> b/src/mesa/main/format_pack.c.mako
> index b846702..c5ad623 100644
> --- a/src/mesa/main/format_pack.c.mako
> +++ b/src/mesa/main/format_pack.c.mako
> @@ -68,7 +68,7 @@ for f in formats:
> /* ubyte packing functions */
>
> %for f in rgb_formats:
> - %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT',
> 'MESA_FORMAT_R11G11B10_FLOAT'):
> + %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT',
> 'MESA_FORMAT_R11G11B10_FLOAT',
> 'MESA_FORMAT_A2R10G10B10_UNORM'):
> <% continue %>
> %elif f.is_compressed():
> <% continue %>
> @@ -137,6 +137,22 @@ pack_ubyte_${f.short_name()}(const
> GLubyte src[4], void *dst)
> %endfor
>
> static inline void
> +pack_ubyte_a2r10g10b10_unorm(const GLubyte src[4], void *dst)
> +{
> + uint8_t a = _mesa_unorm_to_unorm(src[3], 8, 2);
> + uint16_t r = _mesa_unorm_to_unorm(src[0], 8, 10);
> + uint16_t g = _mesa_unorm_to_unorm(src[1], 8, 10);
> + uint16_t b = _mesa_unorm_to_unorm(src[2], 8, 10);
> +
> + uint32_t d = 0;
> + d |= PACK(a, 0, 2);
> + d |= PACK(r, 2, 10);
> + d |= PACK(g, 12, 10);
> + d |= PACK(b, 22, 10);
> + (*(uint32_t *) dst) = d;
> +}
>
>
> The autogen code should be able to handle this. There's no reason for
> special-casing it. The only reason those other two are a special case
> is that they involve strange floating-bit computations.
>
OK, I fixed it.
>
> +
> +static inline void
> pack_ubyte_r9g9b9e5_float(const GLubyte src[4], void *dst)
> {
> GLuint *d = (GLuint *) dst;
> @@ -311,7 +327,7 @@ pack_int_r11g11b10_float(const GLint
> src[4], void *dst)
> /* float packing functions */
>
> %for f in rgb_formats:
> - %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT',
> 'MESA_FORMAT_R11G11B10_FLOAT'):
> + %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT',
> 'MESA_FORMAT_R11G11B10_FLOAT',
> 'MESA_FORMAT_A2R10G10B10_UNORM'):
> <% continue %>
> %elif f.is_compressed():
> <% continue %>
> @@ -373,6 +389,22 @@ pack_float_${f.short_name()}(const
> GLfloat src[4], void *dst)
> %endfor
>
> static inline void
> +pack_float_a2r10g10b10_unorm(const GLfloat src[4], void *dst)
> +{
> + uint8_t a = _mesa_float_to_unorm(src[3], 2);
> + uint16_t r = _mesa_float_to_unorm(src[0], 10);
> + uint16_t g = _mesa_float_to_unorm(src[1], 10);
> + uint16_t b = _mesa_float_to_unorm(src[2], 10);
> +
> + uint32_t d = 0;
> + d |= PACK(a, 0, 2);
> + d |= PACK(r, 2, 10);
> + d |= PACK(g, 12, 10);
> + d |= PACK(b, 22, 10);
> + (*(uint32_t *) dst) = d;
> +}
> +
> +static inline void
> pack_float_r9g9b9e5_float(const GLfloat src[4], void *dst)
> {
> GLuint *d = (GLuint *) dst;
> diff --git a/src/mesa/main/format_unpack.c.mako
> b/src/mesa/main/format_unpack.c.mako
> index 8fd3cdd..510aed2 100644
> --- a/src/mesa/main/format_unpack.c.mako
> +++ b/src/mesa/main/format_unpack.c.mako
> @@ -67,7 +67,7 @@ for f in formats:
> /* float unpacking functions */
>
> %for f in rgb_formats:
> - %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT',
> 'MESA_FORMAT_R11G11B10_FLOAT'):
> + %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT',
> 'MESA_FORMAT_R11G11B10_FLOAT',
> 'MESA_FORMAT_A2R10G10B10_UNORM'):
> <% continue %>
> %elif f.is_compressed():
> <% continue %>
> @@ -128,6 +128,21 @@ unpack_float_${f.short_name()}(const void
> *void_src, GLfloat dst[4])
> }
> %endfor
>
> +static inline void
> +unpack_float_a2r10g10b10_unorm(const void *void_src, GLfloat
> dst[4])
> +{
> + uint32_t *src = (uint32_t *) void_src;
> + uint8_t a = UNPACK(*src, 0, 2);
> + uint16_t r = UNPACK(*src, 2, 10);
> + uint16_t g = UNPACK(*src, 12, 10);
> + uint16_t b = UNPACK(*src, 22, 10);
> +
> + dst[0] = _mesa_unorm_to_float(r, 10);
> + dst[1] = _mesa_unorm_to_float(g, 10);
> + dst[2] = _mesa_unorm_to_float(b, 10);
> + dst[3] = _mesa_unorm_to_float(a, 2);
> +}
> +
> static void
> unpack_float_r9g9b9e5_float(const void *src, GLfloat dst[4])
> {
> @@ -195,7 +210,9 @@ unpack_float_ycbcr_rev(const void *src,
> GLfloat dst[][4], GLuint n)
> /* ubyte packing functions */
>
> %for f in rgb_formats:
> - %if not f.is_normalized():
> + %if f.name in ('MESA_FORMAT_A2R10G10B10_UNORM'):
> + <% continue %>
> + %elif not f.is_normalized():
> <% continue %>
> %endif
>
> @@ -254,6 +271,20 @@ unpack_ubyte_${f.short_name()}(const void
> *void_src, GLubyte dst[4])
> }
> %endfor
>
> +static inline void
> +unpack_ubyte_a2r10g10b10_unorm(const void *void_src, GLubyte
> dst[4])
> +{
> + uint32_t *src = (uint32_t *) void_src;
> + uint8_t a = UNPACK(*src, 0, 2);
> + uint16_t r = UNPACK(*src, 2, 10);
> + uint16_t g = UNPACK(*src, 12, 10);
> + uint16_t b = UNPACK(*src, 22, 10);
> +
> + dst[0] = _mesa_unorm_to_unorm(r, 10, 8);
> + dst[1] = _mesa_unorm_to_unorm(g, 10, 8);
> + dst[2] = _mesa_unorm_to_unorm(b, 10, 8);
> + dst[3] = _mesa_unorm_to_unorm(a, 2, 8);
> +}
>
> /* integer packing functions */
>
> diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
> index f14250b..06e8973 100644
> --- a/src/mesa/main/formats.c
> +++ b/src/mesa/main/formats.c
> @@ -937,6 +937,50 @@
> _mesa_format_to_type_and_comps(mesa_format format,
> *comps = 1;
> return;
>
> + case MESA_FORMAT_R3G3B2_UNORM:
> + *datatype = GL_UNSIGNED_BYTE_2_3_3_REV;
> + *comps = 3;
> + return;
> + case MESA_FORMAT_A4B4G4R4_UNORM:
> + *datatype = GL_UNSIGNED_SHORT_4_4_4_4;
> + *comps = 4;
> + return;
> +
> + case MESA_FORMAT_R4G4B4A4_UNORM:
> + *datatype = GL_UNSIGNED_SHORT_4_4_4_4;
> + *comps = 4;
> + return;
> + case MESA_FORMAT_R1G5B5A5_UNORM:
> + *datatype = GL_UNSIGNED_SHORT_5_5_5_1;
> + *comps = 4;
> + return;
> + case MESA_FORMAT_R5G5B5A1_UNORM:
> + *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV;
> + *comps = 4;
> + return;
> + case MESA_FORMAT_A5B5G5R1_UNORM:
> + *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV;
> + *comps = 4;
> + return;
> + case MESA_FORMAT_A2B10G10R10_UNORM:
> + case MESA_FORMAT_A2B10G10R10_UINT:
> + *datatype = GL_UNSIGNED_INT_10_10_10_2;
> + *comps = 4;
> + return;
> + case MESA_FORMAT_A2R10G10B10_UNORM:
> + case MESA_FORMAT_A2R10G10B10_UINT:
> + *datatype = GL_UNSIGNED_INT_10_10_10_2;
> + *comps = 4;
> + return;
> + case MESA_FORMAT_R2G10B10A10_UNORM:
> + *datatype = GL_UNSIGNED_INT_10_10_10_2;
> + *comps = 4;
> + return;
> + case MESA_FORMAT_A10B10G10R2_UNORM:
> + *datatype = GL_UNSIGNED_INT_2_10_10_10_REV;
> + *comps = 4;
> + return;
> +
> case MESA_FORMAT_B2G3R3_UNORM:
> *datatype = GL_UNSIGNED_BYTE_3_3_2;
> *comps = 3;
> @@ -1581,6 +1625,66 @@
> _mesa_format_matches_format_and_type(mesa_format mesa_format,
> case MESA_FORMAT_B2G3R3_UNORM:
> return format == GL_RGB && type ==
> GL_UNSIGNED_BYTE_3_3_2;
>
> + case MESA_FORMAT_R3G3B2_UNORM:
> + return format == GL_RGB && type ==
> GL_UNSIGNED_BYTE_2_3_3_REV;
> +
> + case MESA_FORMAT_A4B4G4R4_UNORM:
> + if (format == GL_RGBA && type ==
> GL_UNSIGNED_SHORT_4_4_4_4 && !swapBytes)
> + return GL_TRUE;
> +
> + if (format == GL_RGBA && type ==
> GL_UNSIGNED_SHORT_4_4_4_4_REV && swapBytes)
> + return GL_TRUE;
> +
> + if (format == GL_ABGR_EXT && type ==
> GL_UNSIGNED_SHORT_4_4_4_4_REV && !swapBytes)
> + return GL_TRUE;
> +
> + if (format == GL_ABGR_EXT && type ==
> GL_UNSIGNED_SHORT_4_4_4_4 && swapBytes)
> + return GL_TRUE;
> +
> + return GL_FALSE;
> +
> + case MESA_FORMAT_R4G4B4A4_UNORM:
> + if (format == GL_ABGR_EXT && type ==
> GL_UNSIGNED_SHORT_4_4_4_4 && !swapBytes)
> + return GL_TRUE;
> +
> + if (format == GL_ABGR_EXT && type ==
> GL_UNSIGNED_SHORT_4_4_4_4_REV && swapBytes)
> + return GL_TRUE;
> +
> + if (format == GL_RGBA && type ==
> GL_UNSIGNED_SHORT_4_4_4_4_REV && !swapBytes)
> + return GL_TRUE;
> +
> + if (format == GL_RGBA && type ==
> GL_UNSIGNED_SHORT_4_4_4_4 && swapBytes)
> + return GL_TRUE;
> +
> + return GL_FALSE;
> +
> + case MESA_FORMAT_R1G5B5A5_UNORM:
> + return format == GL_ABGR_EXT && type ==
> GL_UNSIGNED_SHORT_5_5_5_1;
> +
> + case MESA_FORMAT_R5G5B5A1_UNORM:
> + return format == GL_RGBA && type ==
> GL_UNSIGNED_SHORT_1_5_5_5_REV;
> +
> + case MESA_FORMAT_A5B5G5R1_UNORM:
> + return format == GL_ABGR_EXT && type ==
> GL_UNSIGNED_SHORT_1_5_5_5_REV;
> +
> + case MESA_FORMAT_A2B10G10R10_UNORM:
> + return format == GL_RGBA && type ==
> GL_UNSIGNED_INT_10_10_10_2;
> +
> + case MESA_FORMAT_A2B10G10R10_UINT:
> + return format == GL_RGBA_INTEGER_EXT && type ==
> GL_UNSIGNED_INT_10_10_10_2;
> +
> + case MESA_FORMAT_A2R10G10B10_UNORM:
> + return format == GL_BGRA && type ==
> GL_UNSIGNED_INT_10_10_10_2;
> +
> + case MESA_FORMAT_A2R10G10B10_UINT:
> + return format == GL_BGRA_INTEGER_EXT && type ==
> GL_UNSIGNED_INT_10_10_10_2;
> +
> + case MESA_FORMAT_R2G10B10A10_UNORM:
> + return format == GL_ABGR_EXT && type ==
> GL_UNSIGNED_INT_10_10_10_2;
> +
> + case MESA_FORMAT_A10B10G10R2_UNORM:
> + return format == GL_ABGR_EXT && type ==
> GL_UNSIGNED_INT_2_10_10_10_REV;
> +
> case MESA_FORMAT_A_UNORM8:
> return format == GL_ALPHA && type == GL_UNSIGNED_BYTE;
> case MESA_FORMAT_A_UNORM16:
> diff --git a/src/mesa/main/formats.csv
> b/src/mesa/main/formats.csv
> index 39bcdbd..6d68427 100644
> --- a/src/mesa/main/formats.csv
> +++ b/src/mesa/main/formats.csv
> @@ -88,6 +88,17 @@ MESA_FORMAT_X8_UINT_Z24_UNORM ,
> packed, 1, 1, un24, x8 , ,
> MESA_FORMAT_Z24_UNORM_S8_UINT , packed, 1, 1,
> u8 , un24, , , yx__, zs
> MESA_FORMAT_Z24_UNORM_X8_UINT , packed, 1, 1,
> x8 , un24, , , y___, zs
>
> +MESA_FORMAT_R3G3B2_UNORM , packed, 1, 1,
> un3 , un3 , un2 , , xyz1, rgb
> +MESA_FORMAT_A4B4G4R4_UNORM , packed, 1, 1,
> un4 , un4 , un4 , un4 , wzyx, rgb
> +MESA_FORMAT_R4G4B4A4_UNORM , packed, 1, 1,
> un4 , un4 , un4 , un4 , xyzw, rgb
> +MESA_FORMAT_R1G5B5A5_UNORM , packed, 1, 1,
> un1 , un5 , un5 , un5 , xyzw, rgb
> +MESA_FORMAT_R5G5B5A1_UNORM , packed, 1, 1,
> un5 , un5 , un5 , un1 , xyzw, rgb
> +MESA_FORMAT_A5B5G5R1_UNORM , packed, 1, 1,
> un5 , un5 , un5 , un1 , wzyx, rgb
> +MESA_FORMAT_A2B10G10R10_UNORM , packed, 1, 1,
> un2 , un10, un10, un10, wzyx, rgb
> +MESA_FORMAT_A2R10G10B10_UNORM , packed, 1, 1,
> un2 , un10, un10, un10, wxyz, rgb
> +MESA_FORMAT_R2G10B10A10_UNORM , packed, 1, 1,
> un2 , un10, un10, un10, xyzw, rgb
> +MESA_FORMAT_A10B10G10R2_UNORM , packed, 1, 1,
> un10, un10, un10, un2 , wzyx, rgb
> +
> MESA_FORMAT_YCBCR , other , 1, 1,
> x16 , , , , xyzw, yuv
> MESA_FORMAT_YCBCR_REV , other , 1, 1,
> x16 , , , , xyzw, yuv
>
> @@ -180,6 +191,8 @@ MESA_FORMAT_Z_FLOAT32
> , array , 1, 1, f32 , , ,
> # Packed signed/unsigned non-normalized integer formats
> MESA_FORMAT_B10G10R10A2_UINT , packed, 1, 1,
> u10 , u10 , u10 , u2 , zyxw, rgb
> MESA_FORMAT_R10G10B10A2_UINT , packed, 1, 1,
> u10 , u10 , u10 , u2 , xyzw, rgb
> +MESA_FORMAT_A2B10G10R10_UINT , packed, 1, 1,
> u2 , u10 , u10 , u10 , wzyx, rgb
> +MESA_FORMAT_A2R10G10B10_UINT , packed, 1, 1,
> u2 , u10 , u10 , u10 , yzwx, rgb
>
> # Array signed/unsigned non-normalized integer formats
> MESA_FORMAT_A_UINT8 , array , 1, 1,
> u8 , , , , 000x, rgb
> diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
> index 7ddf4ee..bba5bae 100644
> --- a/src/mesa/main/formats.h
> +++ b/src/mesa/main/formats.h
> @@ -281,6 +281,19 @@ typedef enum
> MESA_FORMAT_Z24_UNORM_S8_UINT,/* SSSS SSSS ZZZZ ZZZZ ZZZZ
> ZZZZ ZZZZ ZZZZ */
> MESA_FORMAT_Z24_UNORM_X8_UINT,/* xxxx xxxx ZZZZ ZZZZ ZZZZ
> ZZZZ ZZZZ ZZZZ */
>
> + /* Other formats */
> + MESA_FORMAT_R3G3B2_UNORM,
> /* BBGG GRRR */
> + MESA_FORMAT_A4B4G4R4_UNORM, /* RRRR
> GGGG BBBB AAAA */
> + MESA_FORMAT_R4G4B4A4_UNORM, /* AAAA
> BBBB GGGG RRRR */
> + MESA_FORMAT_R1G5B5A5_UNORM, /* AAAA
> ABBB BBGG GGGR */
> + MESA_FORMAT_R5G5B5A1_UNORM, /* ABBB
> BBGG GGGR RRRR */
> + MESA_FORMAT_A5B5G5R1_UNORM, /* RGGG
> GGBB BBBA AAAA */
> + MESA_FORMAT_A2B10G10R10_UNORM,/* RRRR RRRR RRGG GGGG GGGG
> BBBB BBBB BBAA */
> + MESA_FORMAT_A2R10G10B10_UNORM,/* BBBB BBBB BBGG GGGG GGGG
> RRRR RRRR RRAA */
> + MESA_FORMAT_R2G10B10A10_UNORM,/* AAAA AAAA AABB BBBB BBBB
> GGGG GGGG GGRR */
> + MESA_FORMAT_A10B10G10R2_UNORM,/* RRGG GGGG GGGG BBBB BBBB
> BBAA AAAA AAAA */
>
>
> I don't think these formats with 1 or 2 bits for red and more bits for
> alpha actually exist. In the GL spec, it expressly says that 5_5_5_1
> and 10_10_10_2 are only allowed in combination with GL_RGBA or
> GL_BGRA. The GL_ABGR spec doesn't list any interaction with those
> types, so I would assume that it's not allowed.
>
There is one glean test that explicitly checks for those combinations
(pixelFormats). What should we do then? Allow them as current code
does? or just remove them? If remove then the test program crashes
because of the assert at the end of _mesa_format_from_format_and_type(),
so we need to do some changes to avoid that.
I checked what other drivers do in that regard: NVIDIA proprietary driver
allows them and ATI proprietary driver doesn't.
What do you think?
Sam
> --Jason
>
>
>
> +
> +
> MESA_FORMAT_YCBCR, /* YYYY
> YYYY UorV UorV */
> MESA_FORMAT_YCBCR_REV, /* UorV
> UorV YYYY YYYY */
>
> @@ -375,6 +388,8 @@ typedef enum
> /* Packed signed/unsigned non-normalized integer formats
> */
> MESA_FORMAT_B10G10R10A2_UINT, /* AARR RRRR RRRR GGGG GGGG
> GGBB BBBB BBBB */
> MESA_FORMAT_R10G10B10A2_UINT, /* AABB BBBB BBBB GGGG GGGG
> GGRR RRRR RRRR */
> + MESA_FORMAT_A2B10G10R10_UINT, /* RRRR RRRR RRGG GGGG GGGG
> BBBB BBBB BBAA */
> + MESA_FORMAT_A2R10G10B10_UINT, /* BBBB BBBB BBGG GGGG GGGG
> RRRR RRRR RRAA */
>
> /* Array signed/unsigned non-normalized integer formats */
> MESA_FORMAT_A_UINT8,
> diff --git a/src/mesa/swrast/s_texfetch.c
> b/src/mesa/swrast/s_texfetch.c
> index 0f6da91..e9bb5eb 100644
> --- a/src/mesa/swrast/s_texfetch.c
> +++ b/src/mesa/swrast/s_texfetch.c
> @@ -180,6 +180,17 @@ texfetch_funcs[] =
> fetch_texel_2d_Z24_UNORM_S8_UINT,
> fetch_texel_3d_Z24_UNORM_S8_UINT
> },
> + FETCH_NULL(R3G3B2_UNORM),
> + FETCH_NULL(A4B4G4R4_UNORM),
> + FETCH_NULL(R4G4B4A4_UNORM),
> + FETCH_NULL(R1G5B5A5_UNORM),
> + FETCH_NULL(R5G5B5A1_UNORM),
> + FETCH_NULL(A5B5G5R1_UNORM),
> + FETCH_NULL(A2B10G10R10_UNORM),
> + FETCH_NULL(A2R10G10B10_UNORM),
> + FETCH_NULL(R2G10B10A10_UNORM),
> + FETCH_NULL(A10B10G10R2_UNORM),
> +
> FETCH_FUNCS(YCBCR),
> FETCH_FUNCS(YCBCR_REV),
>
> @@ -276,6 +287,8 @@ texfetch_funcs[] =
> /* Packed signed/unsigned non-normalized integer formats
> */
> FETCH_NULL(B10G10R10A2_UINT),
> FETCH_NULL(R10G10B10A2_UINT),
> + FETCH_NULL(A2B10G10R10_UINT),
> + FETCH_NULL(A2R10G10B10_UINT),
>
> /* Array signed/unsigned non-normalized integer formats */
> FETCH_NULL(A_UINT8),
> --
> 1.9.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20141120/e7fb174b/attachment-0001.sig>
More information about the mesa-dev
mailing list