<div dir="ltr">On 24 November 2013 21:00, Francisco Jerez <span dir="ltr"><<a href="mailto:currojerez@riseup.net" target="_blank">currojerez@riseup.net</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Including pack/unpack and texstore code.  This texture format is a<br>
requirement for ARB_shader_image_load_store.<br>
---<br>
 src/mesa/main/format_pack.c   | 29 +++++++++++++++++++++++++++<br>
 src/mesa/main/format_unpack.c | 32 ++++++++++++++++++++++++++++++<br>
 src/mesa/main/formats.c       | 19 ++++++++++++++++++<br>
 src/mesa/main/formats.h       |  2 ++<br>
 src/mesa/main/texstore.c      | 46 +++++++++++++++++++++++++++++++++++++++++++<br>
 src/mesa/swrast/s_texfetch.c  |  6 ++++++<br>
 6 files changed, 134 insertions(+)<br>
<br>
diff --git a/src/mesa/main/format_pack.c b/src/mesa/main/format_pack.c<br>
index 826fc10..9b6929d 100644<br>
--- a/src/mesa/main/format_pack.c<br>
+++ b/src/mesa/main/format_pack.c<br>
@@ -1824,6 +1824,31 @@ pack_float_XBGR32323232_FLOAT(const GLfloat src[4], void *dst)<br>
    d[3] = 1.0;<br>
 }<br>
<br>
+/* MESA_FORMAT_ABGR2101010 */<br>
+<br>
+static void<br>
+pack_ubyte_ABGR2101010(const GLubyte src[4], void *dst)<br>
+{<br>
+   GLuint *d = ((GLuint *) dst);<br>
+   GLushort r = UBYTE_TO_USHORT(src[RCOMP]);<br>
+   GLushort g = UBYTE_TO_USHORT(src[GCOMP]);<br>
+   GLushort b = UBYTE_TO_USHORT(src[BCOMP]);<br>
+   GLushort a = UBYTE_TO_USHORT(src[ACOMP]);<br>
+   *d = PACK_COLOR_2101010_US(a, b, g, r);<br></blockquote><div><br></div><div>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.<br>
<br></div><div>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.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+}<br>
+<br>
+static void<br>
+pack_float_ABGR2101010(const GLfloat src[4], void *dst)<br>
+{<br>
+   GLuint *d = ((GLuint *) dst);<br>
+   GLushort r, g, b, a;<br>
+   UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);<br>
+   UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);<br>
+   UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);<br>
+   UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);<br>
+   *d = PACK_COLOR_2101010_US(a, b, g, r);<br></blockquote><div><br></div><div>This function has similar problems, because PACK_COLOR_2101010_US chops off low order bits, so in effect it always rounds down.<br></div><div>
 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+}<br>
+<br>
<br>
 /**<br>
  * Return a function that can pack a GLubyte rgba[4] color.<br>
@@ -1978,6 +2003,8 @@ _mesa_get_pack_ubyte_rgba_function(gl_format format)<br>
       table[MESA_FORMAT_XBGR32323232_UINT] = NULL;<br>
       table[MESA_FORMAT_XBGR32323232_SINT] = NULL;<br>
<br>
+      table[MESA_FORMAT_ABGR2101010] = pack_ubyte_ABGR2101010;<br>
+<br>
       initialized = GL_TRUE;<br>
    }<br>
<br>
@@ -2136,6 +2163,8 @@ _mesa_get_pack_float_rgba_function(gl_format format)<br>
       table[MESA_FORMAT_XBGR32323232_UINT] = NULL;<br>
       table[MESA_FORMAT_XBGR32323232_SINT] = NULL;<br>
<br>
+      table[MESA_FORMAT_ABGR2101010] = pack_float_ABGR2101010;<br>
+<br>
       initialized = GL_TRUE;<br>
    }<br>
<br>
diff --git a/src/mesa/main/format_unpack.c b/src/mesa/main/format_unpack.c<br>
index 0a8b8b1..fa55930 100644<br>
--- a/src/mesa/main/format_unpack.c<br>
+++ b/src/mesa/main/format_unpack.c<br>
@@ -2268,6 +2268,18 @@ unpack_XBGR32323232_SINT(const void *src, GLfloat dst[][4], GLuint n)<br>
    }<br>
 }<br>
<br>
+static void<br>
+unpack_ABGR2101010(const void *src, GLfloat dst[][4], GLuint n)<br>
+{<br>
+   const GLuint *s = ((const GLuint *) src);<br>
+   GLuint i;<br>
+   for (i = 0; i < n; i++) {<br>
+      dst[i][RCOMP] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F);<br>
+      dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F);<br>
+      dst[i][BCOMP] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F);<br>
+      dst[i][ACOMP] = ((s[i] >> 30) &  0x03) * (1.0F / 3.0F);<br>
+   }<br>
+}<br>
<br>
 /**<br>
  * Return the unpacker function for the given format.<br>
@@ -2481,6 +2493,8 @@ get_unpack_rgba_function(gl_format format)<br>
       table[MESA_FORMAT_XBGR32323232_UINT] = unpack_XBGR32323232_UINT;<br>
       table[MESA_FORMAT_XBGR32323232_SINT] = unpack_XBGR32323232_SINT;<br>
<br>
+      table[MESA_FORMAT_ABGR2101010] = unpack_ABGR2101010;<br>
+<br>
       initialized = GL_TRUE;<br>
    }<br>
<br>
@@ -3582,6 +3596,20 @@ unpack_int_rgba_XBGR32323232_UINT(const GLuint *src, GLuint dst[][4], GLuint n)<br>
    }<br>
 }<br>
<br>
+static void<br>
+unpack_int_rgba_ABGR2101010(const GLuint *src, GLuint dst[][4], GLuint n)<br>
+{<br>
+   unsigned int i;<br>
+<br>
+   for (i = 0; i < n; i++) {<br>
+      GLuint tmp = src[i];<br>
+      dst[i][0] = (tmp >> 0) & 0x3ff;<br>
+      dst[i][1] = (tmp >> 10) & 0x3ff;<br>
+      dst[i][2] = (tmp >> 20) & 0x3ff;<br>
+      dst[i][3] = (tmp >> 30) & 0x3;<br>
+   }<br>
+}<br>
+<br>
 void<br>
 _mesa_unpack_uint_rgba_row(gl_format format, GLuint n,<br>
                            const void *src, GLuint dst[][4])<br>
@@ -3782,6 +3810,10 @@ _mesa_unpack_uint_rgba_row(gl_format format, GLuint n,<br>
       unpack_int_rgba_XBGR32323232_UINT(src, dst, n);<br>
       break;<br>
<br>
+   case MESA_FORMAT_ABGR2101010:<br>
+      unpack_int_rgba_ABGR2101010(src, dst, n);<br>
+      break;<br>
+<br>
    default:<br>
       _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__,<br>
                     _mesa_get_format_name(format));<br>
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c<br>
index 07d2a72..c1ad0a3 100644<br>
--- a/src/mesa/main/formats.c<br>
+++ b/src/mesa/main/formats.c<br>
@@ -1763,6 +1763,15 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =<br>
       0, 0, 0, 0, 0,<br>
       1, 1, 16<br>
    },<br>
+   {<br>
+      MESA_FORMAT_ABGR2101010,<br>
+      "MESA_FORMAT_ABGR2101010",<br>
+      GL_RGBA,<br>
+      GL_UNSIGNED_NORMALIZED,<br>
+      10, 10, 10, 2,<br>
+      0, 0, 0, 0, 0,<br>
+      1, 1, 4<br>
+   },<br>
 };<br>
<br>
<br>
@@ -2821,6 +2830,11 @@ _mesa_format_to_type_and_comps(gl_format format,<br>
       *comps = 4;<br>
       return;<br>
<br>
+   case MESA_FORMAT_ABGR2101010:<br>
+      *datatype = GL_UNSIGNED_INT_2_10_10_10_REV;<br>
+      *comps = 4;<br>
+      return;<br>
+<br>
    case MESA_FORMAT_COUNT:<br>
       assert(0);<br>
       return;<br>
@@ -3362,6 +3376,11 @@ _mesa_format_matches_format_and_type(gl_format gl_format,<br>
    case MESA_FORMAT_XBGR32323232_UINT:<br>
    case MESA_FORMAT_XBGR32323232_SINT:<br>
       return GL_FALSE;<br>
+<br>
+   case MESA_FORMAT_ABGR2101010:<br>
+      return format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV &&<br>
+         !swapBytes;<br>
+<br></blockquote><div><br></div><div>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?<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    }<br>
<br>
    return GL_FALSE;<br>
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h<br>
index 64b4b9a..1bc9339 100644<br>
--- a/src/mesa/main/formats.h<br>
+++ b/src/mesa/main/formats.h<br>
@@ -304,6 +304,8 @@ typedef enum<br>
    MESA_FORMAT_XBGR32323232_UINT, /* ... */<br>
    MESA_FORMAT_XBGR32323232_SINT, /* ... */<br>
<br>
+   MESA_FORMAT_ABGR2101010,<br>
+<br>
    MESA_FORMAT_COUNT<br>
 } gl_format;<br>
<br>
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c<br>
index 76d8d9b..434a906 100644<br>
--- a/src/mesa/main/texstore.c<br>
+++ b/src/mesa/main/texstore.c<br>
@@ -3559,6 +3559,50 @@ _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)<br>
 }<br>
<br>
 static GLboolean<br>
+_mesa_texstore_abgr2101010(TEXSTORE_PARAMS)<br>
+{<br>
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);<br>
+<br>
+   ASSERT(dstFormat == MESA_FORMAT_ABGR2101010);<br>
+   ASSERT(_mesa_get_format_bytes(dstFormat) == 4);<br>
+<br>
+   {<br>
+      /* general path */<br>
+      const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,<br>
+                                                 baseInternalFormat,<br>
+                                                 baseFormat,<br>
+                                                 srcWidth, srcHeight, srcDepth,<br>
+                                                 srcFormat, srcType, srcAddr,<br>
+                                                 srcPacking,<br>
+                                                 ctx->_ImageTransferState);<br>
+      const GLfloat *src = tempImage;<br>
+      GLint img, row, col;<br>
+      if (!tempImage)<br>
+         return GL_FALSE;<br>
+      for (img = 0; img < srcDepth; img++) {<br>
+         GLubyte *dstRow = dstSlices[img];<br>
+<br>
+         for (row = 0; row < srcHeight; row++) {<br>
+            GLuint *dstUI = (GLuint *) dstRow;<br>
+            for (col = 0; col < srcWidth; col++) {<br>
+               GLushort a,r,g,b;<br>
+<br>
+               UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);<br>
+               UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);<br>
+               UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);<br>
+               UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);<br>
+               dstUI[col] = PACK_COLOR_2101010_US(a, b, g, r);<br></blockquote><div><br></div><div>There's a similar loss of accuracy here.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+               src += 4;<br>
+            }<br>
+            dstRow += dstRowStride;<br>
+         }<br>
+      }<br>
+      free((void *) tempImage);<br>
+   }<br>
+   return GL_TRUE;<br>
+}<br>
+<br>
+static GLboolean<br>
 _mesa_texstore_null(TEXSTORE_PARAMS)<br>
 {<br>
    (void) ctx; (void) dims;<br>
@@ -3782,6 +3826,8 @@ _mesa_get_texstore_func(gl_format format)<br>
       table[MESA_FORMAT_XBGR32323232_UINT] = _mesa_texstore_rgba_uint32;<br>
       table[MESA_FORMAT_XBGR32323232_SINT] = _mesa_texstore_rgba_int32;<br>
<br>
+      table[MESA_FORMAT_ABGR2101010] = _mesa_texstore_abgr2101010;<br>
+<br>
       initialized = GL_TRUE;<br>
    }<br>
<br>
diff --git a/src/mesa/swrast/s_texfetch.c b/src/mesa/swrast/s_texfetch.c<br>
index 0196aed..67b3cf7 100644<br>
--- a/src/mesa/swrast/s_texfetch.c<br>
+++ b/src/mesa/swrast/s_texfetch.c<br>
@@ -1286,6 +1286,12 @@ texfetch_funcs[] =<br>
       NULL,<br>
       NULL<br>
    },<br>
+   {<br>
+      MESA_FORMAT_ABGR2101010,<br>
+      NULL,<br>
+      NULL,<br>
+      NULL<br>
+   },<br>
 };<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
--<br>
1.8.3.4<br>
<br>
_______________________________________________<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>
</font></span></blockquote></div><br></div></div>