<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Aug 4, 2014 at 7:55 AM, Brian Paul <span dir="ltr"><<a href="mailto:brianp@vmware.com" target="_blank">brianp@vmware.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="">On 08/02/2014 02:11 PM, Jason Ekstrand wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This commits adds the _mesa_format_to_arary function that determines if the<br>
</blockquote>
<br></div>
"array"<div><div class="h5"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
given format can be represented as an array format and computes the array<br>
format parameters. This is a direct helper function for using<br>
_mesa_swizzle_and_convert<br>
<br>
v2: Better documentation and commit message<br>
<br>
Signed-off-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com" target="_blank">jason.ekstrand@intel.com</a>><br>
---<br>
  src/mesa/main/format_utils.c | 105 ++++++++++++++++++++++++++++++<u></u>+++++++++++++<br>
  src/mesa/main/format_utils.h |   4 ++<br>
  2 files changed, 109 insertions(+)<br>
<br>
diff --git a/src/mesa/main/format_utils.c b/src/mesa/main/format_utils.c<br>
index d60aeb3..95b4612 100644<br>
--- a/src/mesa/main/format_utils.c<br>
+++ b/src/mesa/main/format_utils.c<br>
@@ -55,6 +55,111 @@ _mesa_srgb_ubyte_to_linear_<u></u>float(uint8_t cl)<br>
     return lut[cl];<br>
  }<br>
<br>
+static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 };<br>
+static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 };<br>
+static const uint8_t map_1032[7] = { 1, 0, 3, 2, 4, 5, 6 };<br>
+<br>
+/**<br>
+ * Describes a format as an array format, if possible<br>
+ *<br>
+ * A helper function for figuring out if a (possibly packed) format is<br>
+ * actually an array format and, if so, what the array parameters are.<br>
+ *<br>
+ * \param[in]  format         the mesa format<br>
+ * \param[out] type           the GL type of the array (GL_BYTE, etc.)<br>
+ * \param[out] num_components the number of components in the array<br>
+ * \param[out] swizzle        a swizzle describing how to get from the<br>
+ *                            given format to RGBA<br>
+ * \param[out] normalized     for integer formats, this represents whether<br>
+ *                            the format is a normalized integer or a<br>
+ *                            regular integer<br>
+ * \return  true if this format is an array format, false otherwise<br>
+ */<br>
+bool<br>
+_mesa_format_to_array(mesa_<u></u>format format, GLenum *type, int *num_components,<br>
+                      uint8_t swizzle[4], bool *normalized)<br>
+{<br>
+   int i;<br>
+   GLuint format_components;<br>
+   uint8_t packed_swizzle[4];<br>
+   const uint8_t *endian;<br>
+<br>
+   if (_mesa_is_format_compressed(<u></u>format))<br>
+      return false;<br>
+<br>
+   *normalized = !_mesa_is_format_integer(<u></u>format);<br>
+<br>
+   _mesa_format_to_type_and_<u></u>comps(format, type, &format_components);<br>
+<br>
+   switch (_mesa_get_format_layout(<u></u>format)) {<br>
+   case MESA_FORMAT_LAYOUT_ARRAY:<br>
+      *num_components = format_components;<br>
+      _mesa_get_format_swizzle(<u></u>format, swizzle);<br>
+      return true;<br>
+   case MESA_FORMAT_LAYOUT_PACKED:<br>
+      switch (*type) {<br>
+      case GL_UNSIGNED_BYTE:<br>
+      case GL_BYTE:<br>
+         if (_mesa_get_format_max_bits(<u></u>format) != 8)<br>
+            return false;<br>
+         *num_components = _mesa_get_format_bytes(format)<u></u>;<br>
+         switch (*num_components) {<br>
+         case 1:<br>
+            endian = map_identity;<br>
+            break;<br>
+         case 2:<br>
+            endian = _mesa_little_endian() ? map_identity : map_1032;<br>
+            break;<br>
+         case 4:<br>
+            endian = _mesa_little_endian() ? map_identity : map_3210;<br>
+            break;<br>
+         default:<br>
+            assert(!"Invalid number of components");<br>
</blockquote>
<br></div></div>
I think MSVC (and maybe optimized gcc) will complain than 'endian' is not initialized for all cases.  It would probably be best to initialize endian to point to map_identity[] in the declaration.  If the "impossible" happens and the default case is hit in release build, we should try to not crash.<div class="HOEnZb">
<div class="h5"><br>
<br></div></div></blockquote><div><br></div><div>Thanks Brian, fixed.  I also fixed it for the GL_SHORT case below too.<br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+         }<br>
+         break;<br>
+      case GL_UNSIGNED_SHORT:<br>
+      case GL_SHORT:<br>
+      case GL_HALF_FLOAT:<br>
+         if (_mesa_get_format_max_bits(<u></u>format) != 16)<br>
+            return false;<br>
+         *num_components = _mesa_get_format_bytes(format) / 2;<br>
+         switch (*num_components) {<br>
+         case 1:<br>
+            endian = map_identity;<br>
+            break;<br>
+         case 2:<br>
+            endian = _mesa_little_endian() ? map_identity : map_1032;<br>
+            break;<br>
+         default:<br>
+            assert(!"Invalid number of components");<br>
+         }<br>
+         break;<br>
+      case GL_UNSIGNED_INT:<br>
+      case GL_INT:<br>
+      case GL_FLOAT:<br>
+         /* This isn't packed.  At least not really. */<br>
+         assert(format_components == 1);<br>
+         if (_mesa_get_format_max_bits(<u></u>format) != 32)<br>
+            return false;<br>
+         *num_components = format_components;<br>
+         endian = map_identity;<br>
+         break;<br>
+      default:<br>
+         return false;<br>
+      }<br>
+<br>
+      _mesa_get_format_swizzle(<u></u>format, packed_swizzle);<br>
+<br>
+      for (i = 0; i < 4; ++i)<br>
+         swizzle[i] = endian[packed_swizzle[i]];<br>
+<br>
+      return true;<br>
+   case MESA_FORMAT_LAYOUT_OTHER:<br>
+   default:<br>
+      return false;<br>
+   }<br>
+}<br>
+<br>
  /* A bunch of format conversion macros and helper functions used below */<br>
<br>
  /* Only guaranteed to work for BITS <= 32 */<br>
diff --git a/src/mesa/main/format_utils.h b/src/mesa/main/format_utils.h<br>
index 1a6d7e0..632600e 100644<br>
--- a/src/mesa/main/format_utils.h<br>
+++ b/src/mesa/main/format_utils.h<br>
@@ -65,6 +65,10 @@ _mesa_srgb_to_linear(float cs)<br>
<br>
  float _mesa_srgb_ubyte_to_linear_<u></u>float(uint8_t cl);<br>
<br>
+bool<br>
+_mesa_format_to_array(mesa_<u></u>format, GLenum *type, int *num_components,<br>
+                      uint8_t swizzle[4], bool *normalized);<br>
+<br>
  void<br>
  _mesa_swizzle_and_convert(void *dst, GLenum dst_type, int num_dst_channels,<br>
                            const void *src, GLenum src_type, int num_src_channels,<br>
<br>
</blockquote>
<br>
</div></div></blockquote></div><br></div></div>