[Mesa-dev] [PATCH 06/11] mesa: Add MESA_FORMAT_ABGR2101010.

Paul Berry stereotype441 at gmail.com
Fri Dec 6 09:28:36 PST 2013


On 24 November 2013 21:00, Francisco Jerez <currojerez at riseup.net> wrote:

> Including pack/unpack and texstore code.  This texture format is a
> requirement for ARB_shader_image_load_store.
> ---
>  src/mesa/main/format_pack.c   | 29 +++++++++++++++++++++++++++
>  src/mesa/main/format_unpack.c | 32 ++++++++++++++++++++++++++++++
>  src/mesa/main/formats.c       | 19 ++++++++++++++++++
>  src/mesa/main/formats.h       |  2 ++
>  src/mesa/main/texstore.c      | 46
> +++++++++++++++++++++++++++++++++++++++++++
>  src/mesa/swrast/s_texfetch.c  |  6 ++++++
>  6 files changed, 134 insertions(+)
>
> diff --git a/src/mesa/main/format_pack.c b/src/mesa/main/format_pack.c
> index 826fc10..9b6929d 100644
> --- a/src/mesa/main/format_pack.c
> +++ b/src/mesa/main/format_pack.c
> @@ -1824,6 +1824,31 @@ pack_float_XBGR32323232_FLOAT(const GLfloat src[4],
> void *dst)
>     d[3] = 1.0;
>  }
>
> +/* MESA_FORMAT_ABGR2101010 */
> +
> +static void
> +pack_ubyte_ABGR2101010(const GLubyte src[4], void *dst)
> +{
> +   GLuint *d = ((GLuint *) dst);
> +   GLushort r = UBYTE_TO_USHORT(src[RCOMP]);
> +   GLushort g = UBYTE_TO_USHORT(src[GCOMP]);
> +   GLushort b = UBYTE_TO_USHORT(src[BCOMP]);
> +   GLushort a = UBYTE_TO_USHORT(src[ACOMP]);
> +   *d = PACK_COLOR_2101010_US(a, b, g, r);
>

I don't know if we care, but this conversion is not as accurate as it could
be.  For example, if the input has an r value of 0x3f, then a perfect
conversion would convert this to a float by dividing by 255.0 (to get
0.24706), then convert to 10 bits by multiplying by 1023.0 (to get 252.74),
and then round to the nearest integer, which is 253, or 0xfd.

However, what the function above does is convert to 16 bits (0x3f3f), then
chop off the lower 6 bits by downshifting, to get 0xfc, or 252.


> +}
> +
> +static void
> +pack_float_ABGR2101010(const GLfloat src[4], void *dst)
> +{
> +   GLuint *d = ((GLuint *) dst);
> +   GLushort r, g, b, a;
> +   UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
> +   UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
> +   UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
> +   UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
> +   *d = PACK_COLOR_2101010_US(a, b, g, r);
>

This function has similar problems, because PACK_COLOR_2101010_US chops off
low order bits, so in effect it always rounds down.


> +}
> +
>
>  /**
>   * Return a function that can pack a GLubyte rgba[4] color.
> @@ -1978,6 +2003,8 @@ _mesa_get_pack_ubyte_rgba_function(gl_format format)
>        table[MESA_FORMAT_XBGR32323232_UINT] = NULL;
>        table[MESA_FORMAT_XBGR32323232_SINT] = NULL;
>
> +      table[MESA_FORMAT_ABGR2101010] = pack_ubyte_ABGR2101010;
> +
>        initialized = GL_TRUE;
>     }
>
> @@ -2136,6 +2163,8 @@ _mesa_get_pack_float_rgba_function(gl_format format)
>        table[MESA_FORMAT_XBGR32323232_UINT] = NULL;
>        table[MESA_FORMAT_XBGR32323232_SINT] = NULL;
>
> +      table[MESA_FORMAT_ABGR2101010] = pack_float_ABGR2101010;
> +
>        initialized = GL_TRUE;
>     }
>
> diff --git a/src/mesa/main/format_unpack.c b/src/mesa/main/format_unpack.c
> index 0a8b8b1..fa55930 100644
> --- a/src/mesa/main/format_unpack.c
> +++ b/src/mesa/main/format_unpack.c
> @@ -2268,6 +2268,18 @@ unpack_XBGR32323232_SINT(const void *src, GLfloat
> dst[][4], GLuint n)
>     }
>  }
>
> +static void
> +unpack_ABGR2101010(const void *src, GLfloat dst[][4], GLuint n)
> +{
> +   const GLuint *s = ((const GLuint *) src);
> +   GLuint i;
> +   for (i = 0; i < n; i++) {
> +      dst[i][RCOMP] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F);
> +      dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F);
> +      dst[i][BCOMP] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F);
> +      dst[i][ACOMP] = ((s[i] >> 30) &  0x03) * (1.0F / 3.0F);
> +   }
> +}
>
>  /**
>   * Return the unpacker function for the given format.
> @@ -2481,6 +2493,8 @@ get_unpack_rgba_function(gl_format format)
>        table[MESA_FORMAT_XBGR32323232_UINT] = unpack_XBGR32323232_UINT;
>        table[MESA_FORMAT_XBGR32323232_SINT] = unpack_XBGR32323232_SINT;
>
> +      table[MESA_FORMAT_ABGR2101010] = unpack_ABGR2101010;
> +
>        initialized = GL_TRUE;
>     }
>
> @@ -3582,6 +3596,20 @@ unpack_int_rgba_XBGR32323232_UINT(const GLuint
> *src, GLuint dst[][4], GLuint n)
>     }
>  }
>
> +static void
> +unpack_int_rgba_ABGR2101010(const GLuint *src, GLuint dst[][4], GLuint n)
> +{
> +   unsigned int i;
> +
> +   for (i = 0; i < n; i++) {
> +      GLuint tmp = src[i];
> +      dst[i][0] = (tmp >> 0) & 0x3ff;
> +      dst[i][1] = (tmp >> 10) & 0x3ff;
> +      dst[i][2] = (tmp >> 20) & 0x3ff;
> +      dst[i][3] = (tmp >> 30) & 0x3;
> +   }
> +}
> +
>  void
>  _mesa_unpack_uint_rgba_row(gl_format format, GLuint n,
>                             const void *src, GLuint dst[][4])
> @@ -3782,6 +3810,10 @@ _mesa_unpack_uint_rgba_row(gl_format format, GLuint
> n,
>        unpack_int_rgba_XBGR32323232_UINT(src, dst, n);
>        break;
>
> +   case MESA_FORMAT_ABGR2101010:
> +      unpack_int_rgba_ABGR2101010(src, dst, n);
> +      break;
> +
>     default:
>        _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__,
>                      _mesa_get_format_name(format));
> diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
> index 07d2a72..c1ad0a3 100644
> --- a/src/mesa/main/formats.c
> +++ b/src/mesa/main/formats.c
> @@ -1763,6 +1763,15 @@ static struct gl_format_info
> format_info[MESA_FORMAT_COUNT] =
>        0, 0, 0, 0, 0,
>        1, 1, 16
>     },
> +   {
> +      MESA_FORMAT_ABGR2101010,
> +      "MESA_FORMAT_ABGR2101010",
> +      GL_RGBA,
> +      GL_UNSIGNED_NORMALIZED,
> +      10, 10, 10, 2,
> +      0, 0, 0, 0, 0,
> +      1, 1, 4
> +   },
>  };
>
>
> @@ -2821,6 +2830,11 @@ _mesa_format_to_type_and_comps(gl_format format,
>        *comps = 4;
>        return;
>
> +   case MESA_FORMAT_ABGR2101010:
> +      *datatype = GL_UNSIGNED_INT_2_10_10_10_REV;
> +      *comps = 4;
> +      return;
> +
>     case MESA_FORMAT_COUNT:
>        assert(0);
>        return;
> @@ -3362,6 +3376,11 @@ _mesa_format_matches_format_and_type(gl_format
> gl_format,
>     case MESA_FORMAT_XBGR32323232_UINT:
>     case MESA_FORMAT_XBGR32323232_SINT:
>        return GL_FALSE;
> +
> +   case MESA_FORMAT_ABGR2101010:
> +      return format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV
> &&
> +         !swapBytes;
> +
>

I don't understand the byte ordering conventions in this code well enough
to confirm that this is correct.  Do you have a unit test that validates
that the format is correctly interpreted?


>     }
>
>     return GL_FALSE;
> diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
> index 64b4b9a..1bc9339 100644
> --- a/src/mesa/main/formats.h
> +++ b/src/mesa/main/formats.h
> @@ -304,6 +304,8 @@ typedef enum
>     MESA_FORMAT_XBGR32323232_UINT, /* ... */
>     MESA_FORMAT_XBGR32323232_SINT, /* ... */
>
> +   MESA_FORMAT_ABGR2101010,
> +
>     MESA_FORMAT_COUNT
>  } gl_format;
>
> diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
> index 76d8d9b..434a906 100644
> --- a/src/mesa/main/texstore.c
> +++ b/src/mesa/main/texstore.c
> @@ -3559,6 +3559,50 @@ _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
>  }
>
>  static GLboolean
> +_mesa_texstore_abgr2101010(TEXSTORE_PARAMS)
> +{
> +   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
> +
> +   ASSERT(dstFormat == MESA_FORMAT_ABGR2101010);
> +   ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
> +
> +   {
> +      /* general path */
> +      const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
> +                                                 baseInternalFormat,
> +                                                 baseFormat,
> +                                                 srcWidth, srcHeight,
> srcDepth,
> +                                                 srcFormat, srcType,
> srcAddr,
> +                                                 srcPacking,
> +
> ctx->_ImageTransferState);
> +      const GLfloat *src = tempImage;
> +      GLint img, row, col;
> +      if (!tempImage)
> +         return GL_FALSE;
> +      for (img = 0; img < srcDepth; img++) {
> +         GLubyte *dstRow = dstSlices[img];
> +
> +         for (row = 0; row < srcHeight; row++) {
> +            GLuint *dstUI = (GLuint *) dstRow;
> +            for (col = 0; col < srcWidth; col++) {
> +               GLushort a,r,g,b;
> +
> +               UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
> +               UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
> +               UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
> +               UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
> +               dstUI[col] = PACK_COLOR_2101010_US(a, b, g, r);
>

There's a similar loss of accuracy here.


> +               src += 4;
> +            }
> +            dstRow += dstRowStride;
> +         }
> +      }
> +      free((void *) tempImage);
> +   }
> +   return GL_TRUE;
> +}
> +
> +static GLboolean
>  _mesa_texstore_null(TEXSTORE_PARAMS)
>  {
>     (void) ctx; (void) dims;
> @@ -3782,6 +3826,8 @@ _mesa_get_texstore_func(gl_format format)
>        table[MESA_FORMAT_XBGR32323232_UINT] = _mesa_texstore_rgba_uint32;
>        table[MESA_FORMAT_XBGR32323232_SINT] = _mesa_texstore_rgba_int32;
>
> +      table[MESA_FORMAT_ABGR2101010] = _mesa_texstore_abgr2101010;
> +
>        initialized = GL_TRUE;
>     }
>
> diff --git a/src/mesa/swrast/s_texfetch.c b/src/mesa/swrast/s_texfetch.c
> index 0196aed..67b3cf7 100644
> --- a/src/mesa/swrast/s_texfetch.c
> +++ b/src/mesa/swrast/s_texfetch.c
> @@ -1286,6 +1286,12 @@ texfetch_funcs[] =
>        NULL,
>        NULL
>     },
> +   {
> +      MESA_FORMAT_ABGR2101010,
> +      NULL,
> +      NULL,
> +      NULL
> +   },
>  };
>
>
> --
> 1.8.3.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20131206/4d35ef99/attachment-0001.html>


More information about the mesa-dev mailing list