<div dir="ltr">General comment:  Maybe this would be better in gltypes rather than in mesa_formats<br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 18, 2014 at 1:23 AM, Iago Toral Quiroga <span dir="ltr"><<a href="mailto:itoral@igalia.com" target="_blank">itoral@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">---<br>
 src/mesa/main/formats.c | 285 ++++++++++++++++++++++++++++++++++++++++++++++++<br>
 src/mesa/main/formats.h |   3 +<br>
 2 files changed, 288 insertions(+)<br>
<br>
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c<br>
index 06e8973..7464d89 100644<br>
--- a/src/mesa/main/formats.c<br>
+++ b/src/mesa/main/formats.c<br>
@@ -325,6 +325,291 @@ _mesa_format_from_array_format(uint32_t array_format)<br>
    return MESA_FORMAT_NONE;<br>
 }<br>
<br>
+static void<br>
+_mesa_array_format_set_swizzle(mesa_array_format *array_format,<br>
+                               int x, int y, int z, int w)<br>
+{<br>
+   array_format->swizzle_x = x;<br>
+   array_format->swizzle_y = y;<br>
+   array_format->swizzle_z = z;<br>
+   array_format->swizzle_w = w;<br>
+}<br>
+<br>
+static bool<br>
+_mesa_array_format_set_swizzle_from_format(mesa_array_format *array_format,<br>
+                                           GLenum format)<br>
+{<br>
+   switch (format) {<br>
+   case GL_RGBA:<br>
+   case GL_RGBA_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 0, 1, 2, 3);<br>
+      return true;<br>
+   case GL_BGRA:<br>
+   case GL_BGRA_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 2, 1, 0, 3);<br>
+      return true;<br>
+   case GL_ABGR_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 3, 2, 1, 0);<br>
+      return true;<br>
+   case GL_RGB:<br>
+   case GL_RGB_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 0, 1, 2, 5);<br>
+      return true;<br>
+   case GL_BGR:<br>
+   case GL_BGR_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 2, 1, 0, 5);<br>
+      return true;<br>
+   case GL_LUMINANCE_ALPHA:<br>
+   case GL_LUMINANCE_ALPHA_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 0, 0, 0, 1);<br>
+      return true;<br>
+   case GL_RG:<br>
+   case GL_RG_INTEGER:<br>
+      _mesa_array_format_set_swizzle(array_format, 0, 1, 4, 5);<br>
+      return true;<br>
+   case GL_RED:<br>
+   case GL_RED_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 0, 4, 4, 5);<br>
+      return true;<br>
+   case GL_GREEN:<br>
+   case GL_GREEN_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 4, 0, 4, 5);<br>
+      return true;<br>
+   case GL_BLUE:<br>
+   case GL_BLUE_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 4, 4, 0, 5);<br>
+      return true;<br>
+   case GL_ALPHA:<br>
+   case GL_ALPHA_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 4, 4, 4, 0);<br>
+      return true;<br>
+   case GL_LUMINANCE:<br>
+   case GL_LUMINANCE_INTEGER_EXT:<br>
+      _mesa_array_format_set_swizzle(array_format, 0, 0, 0, 5);<br>
+      return true;<br>
+   case GL_INTENSITY:<br>
+      _mesa_array_format_set_swizzle(array_format, 0, 0, 0, 0);<br>
+      return true;<br>
+   default:<br>
+      return false;<br>
+   }<br>
+}<br>
+<br>
+/**<br>
+* Take an OpenGL format (GL_RGB, GL_RGBA, etc), OpenGL data type (GL_INT,<br>
+* GL_FOAT, etc) and return a matching mesa_array_format or a mesa_format<br>
+* otherwise (for non-array formats).<br>
+*<br>
+* This function will typically be used to compute a mesa format from a GL type<br>
+* so we can then call _mesa_format_convert. This function does<br>
+* not consider byte swapping, so it returns types assuming that no byte<br>
+* swapping is involved. If byte swapping is involved then clients are supposed<br>
+* to handle that on their side before calling _mesa_format_convert.<br>
+*<br>
+* This function returns an uint32_t that can pack a mesa_format or a<br>
+* mesa_array_format. Clients must check the mesa array format bit<br>
+* (MESA_ARRAY_FORMAT_BIT) on the return value to know if the returned<br>
+* format is a mesa_array_format or a mesa_format.<br>
+*/<br>
+uint32_t<br>
+_mesa_format_from_format_and_type(GLenum format, GLenum type)<br>
+{<br>
+   mesa_array_format array_format;<br>
+<br>
+   bool is_array_format = true;<br>
+<br>
+   /* Map the OpenGL data type to an array format data type */<br>
+   switch (type) {<br>
+   case GL_UNSIGNED_BYTE:<br>
+      array_format.type = MESA_ARRAY_FORMAT_TYPE_UBYTE;<br>
+      break;<br>
+   case GL_BYTE:<br>
+      array_format.type = MESA_ARRAY_FORMAT_TYPE_BYTE;<br>
+      break;<br>
+   case GL_UNSIGNED_SHORT:<br>
+      array_format.type = MESA_ARRAY_FORMAT_TYPE_USHORT;<br>
+      break;<br>
+   case GL_SHORT:<br>
+      array_format.type = MESA_ARRAY_FORMAT_TYPE_SHORT;<br>
+      break;<br>
+   case GL_UNSIGNED_INT:<br>
+      array_format.type = MESA_ARRAY_FORMAT_TYPE_UINT;<br>
+      break;<br>
+   case GL_INT:<br>
+      array_format.type = MESA_ARRAY_FORMAT_TYPE_INT;<br>
+      break;<br>
+   case GL_HALF_FLOAT:<br>
+      array_format.type = MESA_ARRAY_FORMAT_TYPE_HALF;<br>
+      break;<br>
+   case GL_FLOAT:<br>
+      array_format.type = MESA_ARRAY_FORMAT_TYPE_FLOAT;<br>
+      break;<br>
+   case GL_UNSIGNED_INT_8_8_8_8:<br>
+   case GL_UNSIGNED_INT_8_8_8_8_REV:<br>
+      array_format.type = MESA_ARRAY_FORMAT_TYPE_UBYTE;<br></blockquote><div><br></div><div>If you put these in the GL type switch below as returning the MESA_FORMAT_R8G8B8A8 or whatever, then the code in mesa_format_get_array_format will fix up the swizzling for you.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      break;<br>
+   default:<br>
+      is_array_format = false;<br>
+      break;<br>
+   }<br>
+<br>
+   /* Next we extract array swizzle information from the OpenGL format */<br>
+   if (is_array_format) {<br>
+      is_array_format =<br>
+         _mesa_array_format_set_swizzle_from_format(&array_format, format);<br>
+   }<br>
+<br>
+   /* If this is an array format type after checking data type and format,<br>
+    * fill in the remaining data<br>
+    */<br>
+   if (is_array_format) {<br>
+      array_format.normalized = !_mesa_is_enum_format_integer(format);<br>
+      array_format.num_channels = _mesa_components_in_format(format);<br>
+      array_format.pad = 0;<br>
+      array_format.array_format_bit = 1;<br>
+<br>
+      /* Check if we need to swap the swizzle for GL_UNSIGNED_INT_8_8_8_8* */<br>
+     bool swap_swizzle =<br>
+         (type == GL_UNSIGNED_INT_8_8_8_8 && _mesa_little_endian()) ||<br>
+         (type == GL_UNSIGNED_INT_8_8_8_8_REV && !_mesa_little_endian());<br>
+      if (swap_swizzle) {<br>
+         GLubyte swizzle[4], tmp[4];<br>
+         const GLubyte map_3210[6] = { 3, 2, 1, 0, 4, 5 };<br>
+         int i;<br>
+<br>
+         tmp[0] = array_format.swizzle_x;<br>
+         tmp[1] = array_format.swizzle_y;<br>
+         tmp[2] = array_format.swizzle_z;<br>
+         tmp[3] = array_format.swizzle_w;<br>
+<br>
+         for (i = 0; i < 4; i++) {<br>
+            if (tmp[i] == MESA_FORMAT_SWIZZLE_NONE)<br>
+               swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;<br>
+            else<br>
+               swizzle[i] = map_3210[tmp[i]];<br>
+         }<br>
+<br>
+         array_format.swizzle_x = swizzle[0];<br>
+         array_format.swizzle_y = swizzle[1];<br>
+         array_format.swizzle_z = swizzle[2];<br>
+         array_format.swizzle_w = swizzle[3];<br>
+      } else if (!_mesa_little_endian()) {<br>
+         array_format = array_format_flip_channels(array_format);<br>
+      }<br>
+      return array_format.as_uint;<br>
+   }<br>
+<br>
+   /* Otherwise this is not an array format, so return the mesa_format<br>
+    * matching the OpenGL format and data type<br>
+    */<br>
+   switch (type) {<br>
+   case GL_UNSIGNED_SHORT_5_6_5:<br>
+     if (format == GL_RGB)<br>
+         return MESA_FORMAT_B5G6R5_UNORM;<br>
+      else if (format == GL_BGR)<br>
+         return MESA_FORMAT_R5G6B5_UNORM;<br>
+      break;<br>
+   case GL_UNSIGNED_SHORT_5_6_5_REV:<br>
+      if (format == GL_RGB)<br>
+         return MESA_FORMAT_R5G6B5_UNORM;<br>
+      else if (format == GL_BGR)<br>
+         return MESA_FORMAT_B5G6R5_UNORM;<br>
+      break;<br>
+   case GL_UNSIGNED_SHORT_4_4_4_4:<br>
+      if (format == GL_RGBA)<br>
+         return MESA_FORMAT_A4B4G4R4_UNORM;<br>
+      else if (format == GL_BGRA)<br>
+         return MESA_FORMAT_A4R4G4B4_UNORM;<br>
+      else if (format == GL_ABGR_EXT)<br>
+         return MESA_FORMAT_R4G4B4A4_UNORM;<br>
+      break;<br>
+   case GL_UNSIGNED_SHORT_4_4_4_4_REV:<br>
+      if (format == GL_RGBA)<br>
+         return MESA_FORMAT_R4G4B4A4_UNORM;<br>
+      else if (format == GL_BGRA)<br>
+         return MESA_FORMAT_B4G4R4A4_UNORM;<br>
+      else if (format == GL_ABGR_EXT)<br>
+         return MESA_FORMAT_A4B4G4R4_UNORM;<br>
+      break;<br>
+   case GL_UNSIGNED_SHORT_5_5_5_1:<br>
+      if (format == GL_RGBA)<br>
+         return MESA_FORMAT_A1B5G5R5_UNORM;<br>
+      else if (format == GL_BGRA)<br>
+         return MESA_FORMAT_A1R5G5B5_UNORM;<br>
+      else if (format == GL_ABGR_EXT)<br>
+         return MESA_FORMAT_R1G5B5A5_UNORM;<br>
+      break;<br>
+   case GL_UNSIGNED_SHORT_1_5_5_5_REV:<br>
+      if (format == GL_RGBA)<br>
+         return MESA_FORMAT_R5G5B5A1_UNORM;<br>
+      else if (format == GL_BGRA)<br>
+         return MESA_FORMAT_B5G5R5A1_UNORM;<br>
+      else if (format == GL_ABGR_EXT)<br>
+         return MESA_FORMAT_A5B5G5R1_UNORM;<br></blockquote><div><br></div><div>I mentioned this in a comment on an earlier patch, but I don't think this combination is a real thing.  If we currently allow it, we should double-check the GL spec and disallow it if we can.  That's just a bad format.<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      break;<br>
+   case GL_UNSIGNED_BYTE_3_3_2:<br>
+      if (format == GL_RGB)<br>
+         return MESA_FORMAT_B2G3R3_UNORM;<br>
+      break;<br>
+   case GL_UNSIGNED_BYTE_2_3_3_REV:<br>
+      if (format == GL_RGB)<br>
+         return MESA_FORMAT_R3G3B2_UNORM;<br>
+      break;<br>
+   case GL_UNSIGNED_INT_5_9_9_9_REV:<br>
+      if (format == GL_RGB)<br>
+         return MESA_FORMAT_R9G9B9E5_FLOAT;<br>
+      break;<br>
+   case GL_UNSIGNED_INT_10_10_10_2:<br>
+      if (format == GL_RGBA)<br>
+         return MESA_FORMAT_A2B10G10R10_UNORM;<br>
+      else if (format == GL_RGBA_INTEGER)<br>
+         return MESA_FORMAT_A2B10G10R10_UINT;<br>
+      else if (format == GL_BGRA)<br>
+         return MESA_FORMAT_A2R10G10B10_UNORM;<br>
+      else if (format == GL_BGRA_INTEGER)<br>
+         return MESA_FORMAT_A2R10G10B10_UINT;<br>
+      else if (format == GL_ABGR_EXT)<br>
+         return MESA_FORMAT_R2G10B10A10_UNORM;<br>
+      break;<br>
+   case GL_UNSIGNED_INT_2_10_10_10_REV:<br>
+      if (format == GL_RGBA)<br>
+         return MESA_FORMAT_R10G10B10A2_UNORM;<br>
+      else if (format == GL_RGBA_INTEGER)<br>
+         return MESA_FORMAT_R10G10B10A2_UINT;<br>
+      else if (format == GL_BGRA)<br>
+         return MESA_FORMAT_B10G10R10A2_UNORM;<br>
+      else if (format == GL_BGRA_INTEGER)<br>
+         return MESA_FORMAT_B10G10R10A2_UINT;<br>
+      else if (format == GL_ABGR_EXT)<br>
+         return MESA_FORMAT_A10B10G10R2_UNORM;<br></blockquote><div><br></div><div>Same here<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      break;<br>
+   case GL_UNSIGNED_INT_8_8_8_8:<br>
+      /* Formats other than BGRA are handled as array formats */<br>
+      if (format == GL_BGRA)<br>
+         return MESA_FORMAT_A8R8G8B8_UNORM;<br>
+      break;<br>
+   case GL_UNSIGNED_SHORT_8_8_MESA:<br>
+      if (format == GL_YCBCR_MESA)<br>
+         return MESA_FORMAT_YCBCR;<br>
+      break;<br>
+   case GL_UNSIGNED_SHORT_8_8_REV_MESA:<br>
+      if (format == GL_YCBCR_MESA)<br>
+         return MESA_FORMAT_YCBCR_REV;<br>
+      break;<br>
+   case GL_UNSIGNED_INT_10F_11F_11F_REV:<br>
+      if (format == GL_RGB)<br>
+         return MESA_FORMAT_R11G11B10_FLOAT;<br>
+   default:<br>
+      break;<br>
+   }<br>
+<br>
+   /* If we got here it means that we could not find a Mesa format that<br>
+    * matches the GL format/type provided. We may need to add a new Mesa<br>
+    * format in that case.<br>
+    */<br>
+   assert(!"Unsupported format");<br>
+}<br>
+<br>
 /** Is the given format a compressed format? */<br>
 GLboolean<br>
 _mesa_is_format_compressed(mesa_format format)<br>
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h<br>
index 7a792d4..092a1a2 100644<br>
--- a/src/mesa/main/formats.h<br>
+++ b/src/mesa/main/formats.h<br>
@@ -546,6 +546,9 @@ _mesa_format_to_array_format(mesa_format format);<br>
 extern mesa_format<br>
 _mesa_format_from_array_format(uint32_t array_format);<br>
<br>
+extern uint32_t<br>
+_mesa_format_from_format_and_type(GLenum format, GLenum type);<br>
+<br>
 extern GLboolean<br>
 _mesa_is_format_compressed(mesa_format format);<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
1.9.1<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>