<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 9, 2014 at 4:06 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">From: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br>
<br>
An array format is a 32-bit integer format identifier that can represent<br>
any format that can be represented as an array of standard GL datatypes.<br>
Whie the MESA_FORMAT enums provide several of these, they don't account for<br>
all of them.<br>
<br>
v2 by Iago Toral Quiroga <<a href="mailto:itoral@igalia.com">itoral@igalia.com</a>>:<br>
 - Implement mesa_array_format as a plain bitfiled uint32_t type instead of<br>
   using a struct inside a union to access the various components packed in<br>
   it. This is necessary to support bigendian properly, as pointed out by<br>
   Ian.<br>
 - Squashed: Make float types normalized<br>
---<br>
 src/mesa/main/format_info.py |  16 +++++<br>
 src/mesa/main/formats.c      |  57 ++++++++++++++++++<br>
 src/mesa/main/formats.h      | 136 ++++++++++++++++++++++++++++++++++++++++++-<br>
 3 files changed, 208 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py<br>
index 7424fe0..fe2063d 100644<br>
--- a/src/mesa/main/format_info.py<br>
+++ b/src/mesa/main/format_info.py<br>
@@ -192,6 +192,22 @@ for fmat in formats:<br>
                                        int(fmat.block_size() / 8))<br>
<br>
    print '      {{ {0} }},'.format(', '.join(map(str, fmat.swizzle)))<br>
+   if fmat.is_array():<br>
+      chan = fmat.array_element()<br>
+      norm = chan.norm or chan.type == parser.FLOAT<br>
+      print '      MESA_ARRAY_FORMAT({0}),'.format(', '.join([<br>
+         str(chan.size / 8),<br>
+         str(int(chan.sign)),<br>
+         str(int(chan.type == parser.FLOAT)),<br>
+         str(int(norm)),<br>
+         str(len(fmat.channels)),<br>
+         str(fmat.swizzle[0]),<br>
+         str(fmat.swizzle[1]),<br>
+         str(fmat.swizzle[2]),<br>
+         str(fmat.swizzle[3]),<br>
+      ]))<br>
+   else:<br>
+      print '      0,'<br>
    print '   },'<br>
<br>
 print '};'<br>
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c<br>
index 676ac27..1259892 100644<br>
--- a/src/mesa/main/formats.c<br>
+++ b/src/mesa/main/formats.c<br>
@@ -71,6 +71,7 @@ struct gl_format_info<br>
    GLubyte BytesPerBlock;<br>
<br>
    uint8_t Swizzle[4];<br>
+   mesa_array_format ArrayFormat;<br>
 };<br>
<br>
 #include "format_info.c"<br>
@@ -269,6 +270,62 @@ _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4])<br>
    memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle));<br>
 }<br>
<br>
+mesa_array_format<br>
+_mesa_array_format_flip_channels(mesa_array_format format)<br>
+{<br>
+   int num_channels;<br>
+   uint8_t swizzle[4];<br>
+<br>
+   num_channels = _mesa_array_format_get_num_channels(format);<br>
+   _mesa_array_format_get_swizzle(format, swizzle);<br>
+<br>
+   if (num_channels == 1)<br>
+      return format;<br>
+<br>
+   if (num_channels == 2) {<br>
+      _mesa_array_format_set_swizzle(&format, swizzle[1], swizzle[0],<br>
+                                     swizzle[2], swizzle[3]);<br>
+      return format;<br>
+   }<br>
+<br>
+   if (num_channels == 4) {<br>
+      _mesa_array_format_set_swizzle(&format, swizzle[3], swizzle[2],<br>
+                                     swizzle[1], swizzle[0]);<br>
+      return format;<br>
+   }<br>
+<br>
+   unreachable("Invalid array format");<br>
+}<br>
+<br>
+uint32_t<br>
+_mesa_format_to_array_format(mesa_format format)<br>
+{<br>
+   const struct gl_format_info *info = _mesa_get_format_info(format);<br>
+   if (_mesa_little_endian())<br>
+      return info->ArrayFormat;<br>
+   else<br>
+      return _mesa_array_format_flip_channels(info->ArrayFormat);<br>
+}<br>
+<br>
+mesa_format<br>
+_mesa_format_from_array_format(uint32_t array_format)<br>
+{<br>
+   mesa_array_format af;<br>
+   unsigned f;<br>
+<br>
+   assert(_mesa_format_is_mesa_array_format(array_format));<br>
+<br>
+   if (_mesa_little_endian())<br>
+      af = array_format;<br>
+   else<br>
+      af = _mesa_array_format_flip_channels(array_format);<br>
+<br>
+   for (f = 1; f < MESA_FORMAT_COUNT; ++f)<br>
+      if (_mesa_get_format_info(f)->ArrayFormat == af)<br>
+         return f;<br>
+<br>
+   return MESA_FORMAT_NONE;<br>
+}<br>
<br>
 /** Is the given format a compressed format? */<br>
 GLboolean<br>
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h<br>
index 213ab56..746a92f 100644<br>
--- a/src/mesa/main/formats.h<br>
+++ b/src/mesa/main/formats.h<br>
@@ -37,7 +37,6 @@<br>
 #include <stdbool.h><br>
 #include <stdint.h><br>
<br>
-<br>
 #ifdef __cplusplus<br>
 extern "C" {<br>
 #endif<br>
@@ -82,6 +81,132 @@ enum {<br>
 };<br>
<br>
 /**<br>
+ * An uint32_t that encodes the information necessary to represent an<br>
+ * array format<br>
+ */<br>
+typedef uint32_t mesa_array_format;<br>
+<br>
+/**<br>
+ * Encoding for valid array format data types<br>
+ */<br>
+enum mesa_array_format_datatype {<br>
+   MESA_ARRAY_FORMAT_TYPE_UBYTE = 0x0,<br>
+   MESA_ARRAY_FORMAT_TYPE_USHORT = 0x1,<br>
+   MESA_ARRAY_FORMAT_TYPE_UINT = 0x2,<br>
+   MESA_ARRAY_FORMAT_TYPE_BYTE = 0x4,<br>
+   MESA_ARRAY_FORMAT_TYPE_SHORT = 0x5,<br>
+   MESA_ARRAY_FORMAT_TYPE_INT = 0x6,<br>
+   MESA_ARRAY_FORMAT_TYPE_HALF = 0xd,<br>
+   MESA_ARRAY_FORMAT_TYPE_FLOAT = 0xe,<br>
+};<br>
+<br>
+/**<br>
+ * An enum useful to encode/decode information stored in a mesa_array_format<br>
+ */<br>
+enum {<br>
+   MESA_ARRAY_FORMAT_TYPE_IS_SIGNED = 0x4,<br>
+   MESA_ARRAY_FORMAT_TYPE_IS_FLOAT = 0x8,<br>
+   MESA_ARRAY_FORMAT_TYPE_NORMALIZED = 0x10,<br>
+   MESA_ARRAY_FORMAT_DATATYPE_MASK = 0xf,<br>
+   MESA_ARRAY_FORMAT_TYPE_MASK = 0x1f,<br>
+   MESA_ARRAY_FORMAT_TYPE_SIZE_MASK = 0x3,<br>
+   MESA_ARRAY_FORMAT_NUM_CHANS_MASK = 0xe0,<br>
+   MESA_ARRAY_FORMAT_SWIZZLE_X_MASK = 0x00700,<br>
+   MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK = 0x03800,<br>
+   MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK = 0x1c000,<br>
+   MESA_ARRAY_FORMAT_SWIZZLE_W_MASK = 0xe0000,<br>
+   MESA_ARRAY_FORMAT_BIT = 0x80000000<br>
+};<br>
+<br>
+#define MESA_ARRAY_FORMAT(SIZE, SIGNED, IS_FLOAT, NORM, NUM_CHANS, \<br>
+      SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W) (                \<br>
+   (((SIZE >> 1)      ) & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK) |      \<br>
+   (((SIGNED)    << 2 ) & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) |      \<br>
+   (((IS_FLOAT)  << 3 ) & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) |       \<br>
+   (((NORM)      << 4 ) & MESA_ARRAY_FORMAT_TYPE_NORMALIZED) |     \<br>
+   (((NUM_CHANS) << 5 ) & MESA_ARRAY_FORMAT_NUM_CHANS_MASK) |      \<br>
+   (((SWIZZLE_X) << 8 ) & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) |      \<br>
+   (((SWIZZLE_Y) << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) |      \<br>
+   (((SWIZZLE_Z) << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) |      \<br>
+   (((SWIZZLE_W) << 17) & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK) |      \<br>
+   MESA_ARRAY_FORMAT_BIT)<br>
+<br>
+/**<br>
+ * Various helpers to access the data encoded in a mesa_array_format<br>
+ */<br>
+static inline bool<br>
+_mesa_array_format_is_signed(mesa_array_format f)<br>
+{<br>
+   return (f & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) > 0;<br>
+}<br>
+<br>
+static inline bool<br>
+_mesa_array_format_is_float(mesa_array_format f)<br>
+{<br>
+   return (f & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) > 0;<br>
+}<br>
+<br>
+static inline bool<br>
+_mesa_array_format_is_normalized(mesa_array_format f)<br>
+{<br>
+   return (f & MESA_ARRAY_FORMAT_TYPE_NORMALIZED) > 0;<br>
+}<br></blockquote><div> <br></div><div>Any particular reason why you do "> 0" instead of "!= 0"?  I don't care that much.  Just curious<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+static inline enum mesa_array_format_datatype<br>
+_mesa_array_format_get_datatype(mesa_array_format f)<br>
+{<br>
+   return (enum mesa_array_format_datatype)<br>
+            (f & MESA_ARRAY_FORMAT_DATATYPE_MASK);<br>
+}<br>
+<br>
+static inline int<br>
+_mesa_array_format_datatype_get_size(enum mesa_array_format_datatype type)<br>
+{<br>
+   return 1 << (type & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK);<br>
+}<br>
+<br>
+static inline int<br>
+_mesa_array_format_get_type_size(mesa_array_format f)<br>
+{<br>
+   return 1 << (f & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK);<br>
+}<br>
+<br>
+static inline int<br>
+_mesa_array_format_get_num_channels(mesa_array_format f)<br>
+{<br>
+   return (f & MESA_ARRAY_FORMAT_NUM_CHANS_MASK) >> 5;<br>
+}<br>
+<br>
+static inline void<br>
+_mesa_array_format_get_swizzle(mesa_array_format f, uint8_t *swizzle)<br>
+{<br>
+   swizzle[0] = (f & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) >> 8;<br>
+   swizzle[1] = (f & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) >> 11;<br>
+   swizzle[2] = (f & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) >> 14;<br>
+   swizzle[3] = (f & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK) >> 17;<br>
+}<br>
+<br>
+static inline void<br>
+_mesa_array_format_set_swizzle(mesa_array_format *f,<br>
+                               int32_t x, int32_t y, int32_t z, int32_t w)<br>
+{<br>
+   *f |= ((x << 8 ) & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) |<br>
+         ((y << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) |<br>
+         ((z << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) |<br>
+         ((w << 17) & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK);<br>
+}<br>
+<br>
+/**<br>
+ * A helper to know if the format stored in a uint32_t is a mesa_format<br>
+ * or a mesa_array_format<br>
+ */<br>
+static inline bool<br>
+_mesa_format_is_mesa_array_format(uint32_t f)<br>
+{<br>
+   return (f & MESA_ARRAY_FORMAT_BIT) > 0;<br>
+}<br>
+<br>
+/**<br>
  * Mesa texture/renderbuffer image formats.<br>
  */<br>
 typedef enum<br>
@@ -466,9 +591,18 @@ _mesa_get_format_base_format(mesa_format format);<br>
 extern void<br>
 _mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh);<br>
<br>
+extern mesa_array_format<br>
+_mesa_array_format_flip_channels(mesa_array_format format);<br>
+<br>
 extern void<br>
 _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]);<br>
<br>
+extern uint32_t<br>
+_mesa_format_to_array_format(mesa_format format);<br>
+<br>
+extern mesa_format<br>
+_mesa_format_from_array_format(uint32_t array_format);<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>