<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Nov 20, 2014 at 1:48 AM, Iago Toral <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"><div class="HOEnZb"><div class="h5">On Wed, 2014-11-19 at 11:28 -0800, Jason Ekstrand wrote:<br>
> By and large, this looks good to me.  Most of my comments are cosmetic<br>
> or suggestions for added documentation.  There is one issue that I<br>
> think is subtly wrong with integer format conversion but that should<br>
> be easy to fix.<br>
><br>
> --Jason<br>
><br>
> On Tue, Nov 18, 2014 at 1:23 AM, Iago Toral Quiroga<br>
> <<a href="mailto:itoral@igalia.com">itoral@igalia.com</a>> wrote:<br>
>         From: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br>
><br>
>         v2 by Iago Toral <<a href="mailto:itoral@igalia.com">itoral@igalia.com</a>>:<br>
><br>
>         - When testing if we can directly pack we should use the src<br>
>         format to check<br>
>           if we are packing from an RGBA format. The original code<br>
>         used the dst format<br>
>           for the ubyte case by mistake.<br>
>         - Fixed incorrect number of bits for dst, it was computed<br>
>         using the src format<br>
>           instead of the dst format.<br>
>         - If the dst format is an array format, check if it is signed.<br>
>         We were only<br>
>           checking this for the case where it was not an array format,<br>
>         but we need<br>
>           to know this in both scenarios.<br>
>         - Fixed incorrect swizzle transform for the cases where we<br>
>         convert between<br>
>           array formats.<br>
>         - Compute is_signed and bits only once and for the dst format.<br>
>         We were<br>
>           computing these for the src format too but they were<br>
>         overwritten by the<br>
>           dst values immediately after.<br>
>         - Be more careful when selecting the integer path.<br>
>         Specifically, check that<br>
>           both src and dst are integer types. Checking only one of<br>
>         them should suffice<br>
>           since OpenGL does not allow conversions between normalized<br>
>         and integer types,<br>
>           but putting extra care here makes sense and also makes the<br>
>         actual requirements<br>
>           for this path more clear.<br>
>         - The format argument for pack functions is the destination<br>
>         format we are<br>
>           packing to, not the source format (which has to be RGBA).<br>
>         - Expose RGBA8888_* to other files. These will come in handy<br>
>         when in need to<br>
>           test if a given array format is RGBA or in need to pass RGBA<br>
>         formats to<br>
>           mesa_format_convert.<br>
><br>
>         v3 by Samuel Iglesias <<a href="mailto:siglesias@igalia.com">siglesias@igalia.com</a>>:<br>
><br>
>         - Add an RGBA8888_INT definition.<br>
>         ---<br>
>          src/mesa/main/format_utils.c | 378<br>
>         +++++++++++++++++++++++++++++++++++++++++++<br>
>          src/mesa/main/format_utils.h |  10 ++<br>
>          src/mesa/main/formats.h      |  15 +-<br>
>          3 files changed, 399 insertions(+), 4 deletions(-)<br>
><br>
>         diff --git a/src/mesa/main/format_utils.c<br>
>         b/src/mesa/main/format_utils.c<br>
>         index fcbbba4..c3815cb 100644<br>
>         --- a/src/mesa/main/format_utils.c<br>
>         +++ b/src/mesa/main/format_utils.c<br>
>         @@ -25,6 +25,384 @@<br>
>          #include "format_utils.h"<br>
>          #include "glformats.h"<br>
>          #include "macros.h"<br>
>         +#include "format_pack.h"<br>
>         +#include "format_unpack.h"<br>
>         +<br>
>         +mesa_array_format RGBA8888_FLOAT = {{<br>
>         +   MESA_ARRAY_FORMAT_TYPE_FLOAT,<br>
>         +   0,<br>
>         +   4,<br>
>         +   0, 1, 2, 3,<br>
>         +   0, 1<br>
>         +}};<br>
>         +<br>
>         +mesa_array_format RGBA8888_UBYTE = {{<br>
>         +   MESA_ARRAY_FORMAT_TYPE_UBYTE,<br>
>         +   1,<br>
>         +   4,<br>
>         +   0, 1, 2, 3,<br>
>         +   0, 1<br>
>         +}};<br>
>         +<br>
>         +mesa_array_format RGBA8888_UINT = {{<br>
>         +   MESA_ARRAY_FORMAT_TYPE_UINT,<br>
>         +   0,<br>
>         +   4,<br>
>         +   0, 1, 2, 3,<br>
>         +   0, 1<br>
>         +}};<br>
>         +<br>
>         +mesa_array_format RGBA8888_INT = {{<br>
>         +   MESA_ARRAY_FORMAT_TYPE_INT,<br>
>         +   0,<br>
>         +   4,<br>
>         +   0, 1, 2, 3,<br>
>         +   0, 1<br>
>         +}};<br>
>         +<br>
>         +static void<br>
>         +invert_swizzle(uint8_t dst[4], const uint8_t src[4])<br>
>         +{<br>
>         +   int i, j;<br>
>         +<br>
>         +   dst[0] = MESA_FORMAT_SWIZZLE_NONE;<br>
>         +   dst[1] = MESA_FORMAT_SWIZZLE_NONE;<br>
>         +   dst[2] = MESA_FORMAT_SWIZZLE_NONE;<br>
>         +   dst[3] = MESA_FORMAT_SWIZZLE_NONE;<br>
>         +<br>
>         +   for (i = 0; i < 4; ++i)<br>
>         +      for (j = 0; j < 4; ++j)<br>
>         +         if (src[j] == i && dst[i] ==<br>
>         MESA_FORMAT_SWIZZLE_NONE)<br>
>         +            dst[i] = j;<br>
>         +}<br>
>         +<br>
>         +static GLenum<br>
>         +gl_type_for_array_format_datatype(enum<br>
>         mesa_array_format_datatype type)<br>
>         +{<br>
>         +   switch (type) {<br>
>         +   case MESA_ARRAY_FORMAT_TYPE_UBYTE:<br>
>         +      return GL_UNSIGNED_BYTE;<br>
>         +   case MESA_ARRAY_FORMAT_TYPE_USHORT:<br>
>         +      return GL_UNSIGNED_SHORT;<br>
>         +   case MESA_ARRAY_FORMAT_TYPE_UINT:<br>
>         +      return GL_UNSIGNED_INT;<br>
>         +   case MESA_ARRAY_FORMAT_TYPE_BYTE:<br>
>         +      return GL_BYTE;<br>
>         +   case MESA_ARRAY_FORMAT_TYPE_SHORT:<br>
>         +      return GL_SHORT;<br>
>         +   case MESA_ARRAY_FORMAT_TYPE_INT:<br>
>         +      return GL_INT;<br>
>         +   case MESA_ARRAY_FORMAT_TYPE_HALF:<br>
>         +      return GL_HALF_FLOAT;<br>
>         +   case MESA_ARRAY_FORMAT_TYPE_FLOAT:<br>
>         +      return GL_FLOAT;<br>
>         +   default:<br>
>         +      assert(!"Invalid datatype");<br>
>         +      return GL_NONE;<br>
>         +   }<br>
>         +}<br>
><br>
><br>
> We should probably just make _mesa_swizzle_and_convert take these<br>
> instead of the GL types.  That way we can completely remove GL from<br>
> the format conversion code.  I'm fine if that's a separate patch on<br>
> top.<br>
<br>
</div></div>Ok, I will try this.<br>
<br>
Just out of curiosity: is there any gain in avoiding the GL types in the<br>
conversion code?<br></blockquote><div><br></div><div>As I said in my reply to Jose on the 00/20 patch, we would like to eventually move the format conversion stuff to a common helper library that can be shared by mesa main and the gallium code.  If we are going to do that, then we don't want any GL dependencies.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
><br>
> Also, it would be good to have a nice descriptive docstring on the<br>
> function below.<br>
><br>
<br>
</span>Oh, right!<br>
<div><div class="h5"><br>
><br>
>         +<br>
>         +void<br>
>         +_mesa_format_convert(void *void_dst, uint32_t dst_format,<br>
>         size_t dst_stride,<br>
>         +                     void *void_src, uint32_t src_format,<br>
>         size_t src_stride,<br>
>         +                     size_t width, size_t height)<br>
>         +{<br>
>         +   uint8_t *dst = (uint8_t *)void_dst;<br>
>         +   uint8_t *src = (uint8_t *)void_src;<br>
>         +   mesa_array_format src_array_format, dst_array_format;<br>
>         +   uint8_t src2dst[4], src2rgba[4], rgba2dst[4], dst2rgba[4];<br>
>         +   GLenum src_gl_type, dst_gl_type, common_gl_type;<br>
>         +   bool normalized, dst_integer, src_integer, is_signed;<br>
>         +   uint8_t (*tmp_ubyte)[4];<br>
>         +   float (*tmp_float)[4];<br>
>         +   uint32_t (*tmp_uint)[4];<br>
>         +   int i, bits;<br>
>         +   size_t row;<br>
>         +<br>
>         +   if (src_format & MESA_ARRAY_FORMAT_BIT) {<br>
>         +      src_array_format.as_uint = src_format;<br>
>         +   } else {<br>
>         +      assert(_mesa_is_format_color_format(src_format));<br>
>         +      src_array_format.as_uint =<br>
>         _mesa_format_to_array_format(src_format);<br>
>         +   }<br>
>         +<br>
>         +   if (dst_format & MESA_ARRAY_FORMAT_BIT) {<br>
>         +      dst_array_format.as_uint = dst_format;<br>
>         +   } else {<br>
>         +      assert(_mesa_is_format_color_format(dst_format));<br>
>         +      dst_array_format.as_uint =<br>
>         _mesa_format_to_array_format(dst_format);<br>
>         +   }<br>
>         +<br>
>         +   /* Handle the cases where we can directly unpack */<br>
>         +   if (!(src_format & MESA_ARRAY_FORMAT_BIT)) {<br>
>         +      if (dst_array_format.as_uint == RGBA8888_FLOAT.as_uint)<br>
>         {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_unpack_rgba_row(src_format, width,<br>
>         +                                  src, (float (*)[4])dst);<br>
>         +            src += src_stride;<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +         return;<br>
>         +      } else if (dst_array_format.as_uint ==<br>
>         RGBA8888_UBYTE.as_uint) {<br>
>         +         assert(!_mesa_is_format_integer_color(src_format));<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_unpack_ubyte_rgba_row(src_format, width,<br>
>         +                                        src, (uint8_t<br>
>         (*)[4])dst);<br>
>         +            src += src_stride;<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +         return;<br>
>         +      } else if (dst_array_format.as_uint ==<br>
>         RGBA8888_UINT.as_uint) {<br>
>         +         assert(_mesa_is_format_integer_color(src_format));<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_unpack_uint_rgba_row(src_format, width,<br>
>         +                                       src, (uint32_t<br>
>         (*)[4])dst);<br>
>         +            src += src_stride;<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +         return;<br>
>         +      }<br>
>         +   }<br>
>         +<br>
>         +   /* Handle the cases where we can directly pack */<br>
>         +   if (!(dst_format & MESA_ARRAY_FORMAT_BIT)) {<br>
>         +      if (src_array_format.as_uint == RGBA8888_FLOAT.as_uint)<br>
>         {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_pack_float_rgba_row(dst_format, width,<br>
>         +                                      (const float<br>
>         (*)[4])src, dst);<br>
>         +            src += src_stride;<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +         return;<br>
>         +      } else if (src_array_format.as_uint ==<br>
>         RGBA8888_UBYTE.as_uint) {<br>
>         +         assert(!_mesa_is_format_integer_color(dst_format));<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_pack_ubyte_rgba_row(dst_format, width,<br>
>         +                                      (const uint8_t<br>
>         (*)[4])src, dst);<br>
>         +            src += src_stride;<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +         return;<br>
>         +      } else if (src_array_format.as_uint ==<br>
>         RGBA8888_UINT.as_uint) {<br>
>         +         assert(_mesa_is_format_integer_color(dst_format));<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_pack_uint_rgba_row(dst_format, width,<br>
>         +                                     (const uint32_t<br>
>         (*)[4])src, dst);<br>
>         +            src += src_stride;<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +         return;<br>
>         +      }<br>
>         +   }<br>
>         +<br>
>         +   /* Handle conversions between array formats */<br>
>         +   normalized = false;<br>
>         +   if (src_array_format.as_uint) {<br>
>         +      src_gl_type =<br>
>         gl_type_for_array_format_datatype(src_array_format.type);<br>
>         +<br>
>         +      src2rgba[0] = src_array_format.swizzle_x;<br>
>         +      src2rgba[1] = src_array_format.swizzle_y;<br>
>         +      src2rgba[2] = src_array_format.swizzle_z;<br>
>         +      src2rgba[3] = src_array_format.swizzle_w;<br>
>         +<br>
>         +      normalized = src_array_format.normalized;<br>
>         +   }<br>
>         +<br>
>         +   if (dst_array_format.as_uint) {<br>
>         +      dst_gl_type =<br>
>         gl_type_for_array_format_datatype(dst_array_format.type);<br>
>         +<br>
>         +      dst2rgba[0] = dst_array_format.swizzle_x;<br>
>         +      dst2rgba[1] = dst_array_format.swizzle_y;<br>
>         +      dst2rgba[2] = dst_array_format.swizzle_z;<br>
>         +      dst2rgba[3] = dst_array_format.swizzle_w;<br>
>         +<br>
>         +      invert_swizzle(rgba2dst, dst2rgba);<br>
>         +<br>
>         +      normalized |= dst_array_format.normalized;<br>
>         +   }<br>
>         +<br>
>         +   if (src_array_format.as_uint && dst_array_format.as_uint)<br>
>         {<br>
>         +      assert(src_array_format.normalized ==<br>
>         dst_array_format.normalized);<br>
>         +<br>
>         +      for (i = 0; i < 4; i++) {<br>
>         +         if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) {<br>
>         +            src2dst[i] = rgba2dst[i];<br>
>         +         } else {<br>
>         +            src2dst[i] = src2rgba[rgba2dst[i]];<br>
>         +         }<br>
>         +      }<br>
>         +<br>
>         +      for (row = 0; row < height; ++row) {<br>
>         +         _mesa_swizzle_and_convert(dst, dst_gl_type,<br>
>         dst_array_format.num_channels,<br>
>         +                                   src, src_gl_type,<br>
>         src_array_format.num_channels,<br>
>         +                                   src2dst, normalized,<br>
>         width);<br>
>         +         src += src_stride;<br>
>         +         dst += dst_stride;<br>
>         +      }<br>
>         +      return;<br>
>         +   }<br>
>         +<br>
>         +   /* At this point, we're fresh out of fast-paths and we<br>
>         need to convert<br>
>         +    * to float, uint32, or, if we're lucky, uint8.<br>
>         +    */<br>
>         +   dst_integer = false;<br>
>         +   src_integer = false;<br>
>         +<br>
>         +   if (src_array_format.array_format_bit) {<br>
>         +      if (!(src_array_format.type &<br>
>         MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) &&<br>
>         +          !src_array_format.normalized)<br>
>         +         src_integer = true;<br>
>         +   } else {<br>
>         +      switch (_mesa_get_format_datatype(src_format)) {<br>
>         +      case GL_UNSIGNED_INT:<br>
>         +      case GL_INT:<br>
>         +         src_integer = true;<br>
>         +         break;<br>
>         +      }<br>
>         +   }<br>
>         +<br>
>         +   if (dst_array_format.array_format_bit) {<br>
>         +      if (!(dst_array_format.type &<br>
>         MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) &&<br>
>         +          !dst_array_format.normalized)<br>
>         +         dst_integer = true;<br>
>         +      is_signed = dst_array_format.as_uint &<br>
>         MESA_ARRAY_FORMAT_TYPE_IS_SIGNED;<br>
>         +      bits = 8 *<br>
>         _mesa_array_format_datatype_size(dst_array_format.type);<br>
>         +   } else {<br>
><br>
><br>
> It's worth a quick comment here as to why we only need to look at the<br>
> destination in order to determine the signedness of the intermediate<br>
> storage.  What it comes down to is this:  If the destination format is<br>
> signed but the source is unsigned, then we don't loose any data by<br>
> converting to a signed format above and beyond the precision that we<br>
> loose in the conversion itself.  If the destination is unsigned then,<br>
> by using an unsigned intermediate format, we make the conversion<br>
> function that converts from the source to the intermediate format take<br>
> care of truncating at zero.  The exception here is if the intermediate<br>
> format is float, in which case the first conversion will leave it<br>
> signed and the second conversion will truncate at zero.<br>
<br>
</div></div>Sure, I'll add a comment.<br>
<div><div class="h5"><br>
><br>
>         +      switch (_mesa_get_format_datatype(dst_format)) {<br>
>         +      case GL_UNSIGNED_NORMALIZED:<br>
>         +         is_signed = false;<br>
>         +         break;<br>
>         +      case GL_SIGNED_NORMALIZED:<br>
>         +         is_signed = true;<br>
>         +         break;<br>
>         +      case GL_FLOAT:<br>
>         +         is_signed = true;<br>
>         +         break;<br>
>         +      case GL_UNSIGNED_INT:<br>
>         +         is_signed = false;<br>
>         +         dst_integer = true;<br>
>         +         break;<br>
>         +      case GL_INT:<br>
>         +         is_signed = true;<br>
>         +         dst_integer = true;<br>
>         +         break;<br>
>         +      }<br>
>         +      bits = _mesa_get_format_max_bits(dst_format);<br>
>         +   }<br>
>         +<br>
>         +   assert((src_integer && dst_integer) || (!src_integer && !<br>
>         dst_integer));<br>
><br>
><br>
> Wouldn't src_integer == dst_integer be a bit more clear here?<br>
<br>
</div></div>Right, I guess I was a bit thick when I wrote that :)<br>
<span class=""><br>
><br>
>         +<br>
>         +   if (src_integer && dst_integer) {<br>
>         +      tmp_uint = malloc(width * height * sizeof(*tmp_uint));<br>
><br>
><br>
> There's another quick comment that would be good here.  Namely that<br>
> the [un]packing functions for unsigned datatypes treat the 32-bit<br>
> integer array as signed for signed formats and as unsigned for<br>
> unsigned formats.  This is a bit of a problem if we ever convert from<br>
> a signed to an unsigned format because the unsigned packing function<br>
> doesn't know that the input is signed and will treat it as unsigned<br>
> and not do the trunctation.  The thing that saves us here is that all<br>
> of the packed formats are unsigned, so we can just always use<br>
> _mesa_swizzle_and_convert for signed formats and it is aware of the<br>
> truncation problem.  This may be worth an assertion somewhere.<br>
<br>
</span>Sure, that's helpful.<br>
<span class=""><br>
><br>
><br>
>         +      common_gl_type = is_signed ? GL_INT : GL_UNSIGNED_INT;<br>
>         +<br>
>         +      if (src_format & MESA_ARRAY_FORMAT_BIT) {<br>
><br>
><br>
> In light of the above coment, I think we want to use "if<br>
> (src_array_format)" to ensure that we use _mesa_swizzle_and_convert<br>
> for all signed source formats<br>
<br>
</span>I will try this.<br>
<span class=""><br>
><br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_swizzle_and_convert(tmp_uint + row * width,<br>
>         common_gl_type, 4,<br>
>         +                                      src, src_gl_type,<br>
>         +<br>
>         src_array_format.num_channels,<br>
>         +                                      src2rgba, normalized,<br>
>         width);<br>
>         +            src += src_stride;<br>
>         +         }<br>
>         +      } else {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_unpack_uint_rgba_row(src_format, width,<br>
>         +                                       src, tmp_uint + row *<br>
>         width);<br>
>         +            src += src_stride;<br>
>         +         }<br>
>         +      }<br>
>         +<br>
>         +      if (dst_format & MESA_ARRAY_FORMAT_BIT) {<br>
><br>
><br>
> This one's fine because, at this point, we have already done the<br>
> truncation if the source is signed but the destination is unsigned.<br>
<br>
</span>I'll add a commment to clarify this too.<br>
<div><div class="h5"><br>
><br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_swizzle_and_convert(dst, dst_gl_type,<br>
>         +<br>
>         dst_array_format.num_channels,<br>
>         +                                      tmp_uint + row * width,<br>
>         common_gl_type, 4,<br>
>         +                                      rgba2dst, normalized,<br>
>         width);<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +      } else {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_pack_uint_rgba_row(dst_format, width,<br>
>         +                                     (const uint32_t<br>
>         (*)[4])tmp_uint + row * width, dst);<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +      }<br>
>         +<br>
>         +      free(tmp_uint);<br>
>         +   } else if (is_signed || bits > 8) {<br>
>         +      tmp_float = malloc(width * height *<br>
>         sizeof(*tmp_float));<br>
>         +<br>
>         +      if (src_format & MESA_ARRAY_FORMAT_BIT) {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_swizzle_and_convert(tmp_float + row *<br>
>         width, GL_FLOAT, 4,<br>
>         +                                      src, src_gl_type,<br>
>         +<br>
>         src_array_format.num_channels,<br>
>         +                                      src2rgba, normalized,<br>
>         width);<br>
>         +            src += src_stride;<br>
>         +         }<br>
>         +      } else {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_unpack_rgba_row(src_format, width,<br>
>         +                                  src, tmp_float + row *<br>
>         width);<br>
>         +            src += src_stride;<br>
>         +         }<br>
>         +      }<br>
>         +<br>
>         +      if (dst_format & MESA_ARRAY_FORMAT_BIT) {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_swizzle_and_convert(dst, dst_gl_type,<br>
>         +<br>
>         dst_array_format.num_channels,<br>
>         +                                      tmp_float + row *<br>
>         width, GL_FLOAT, 4,<br>
>         +                                      rgba2dst, normalized,<br>
>         width);<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +      } else {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_pack_float_rgba_row(dst_format, width,<br>
>         +                                      (const float<br>
>         (*)[4])tmp_float + row * width, dst);<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +      }<br>
>         +<br>
>         +      free(tmp_float);<br>
>         +   } else {<br>
>         +      tmp_ubyte = malloc(width * height *<br>
>         sizeof(*tmp_ubyte));<br>
>         +<br>
>         +      if (src_format & MESA_ARRAY_FORMAT_BIT) {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_swizzle_and_convert(tmp_ubyte + row *<br>
>         width, GL_UNSIGNED_BYTE, 4,<br>
>         +                                      src, src_gl_type,<br>
>         +<br>
>         src_array_format.num_channels,<br>
>         +                                      src2rgba, normalized,<br>
>         width);<br>
>         +            src += src_stride;<br>
>         +         }<br>
>         +      } else {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_unpack_ubyte_rgba_row(src_format, width,<br>
>         +                                        src, tmp_ubyte + row<br>
>         * width);<br>
>         +            src += src_stride;<br>
>         +         }<br>
>         +      }<br>
>         +<br>
>         +      if (dst_format & MESA_ARRAY_FORMAT_BIT) {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_swizzle_and_convert(dst, dst_gl_type,<br>
>         +<br>
>         dst_array_format.num_channels,<br>
>         +                                      tmp_ubyte + row *<br>
>         width, GL_UNSIGNED_BYTE, 4,<br>
>         +                                      rgba2dst, normalized,<br>
>         width);<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +      } else {<br>
>         +         for (row = 0; row < height; ++row) {<br>
>         +            _mesa_pack_ubyte_rgba_row(dst_format, width,<br>
>         +                                      (const uint8_t<br>
>         (*)[4])tmp_ubyte + row * width, dst);<br>
>         +            dst += dst_stride;<br>
>         +         }<br>
>         +      }<br>
>         +<br>
>         +      free(tmp_ubyte);<br>
>         +   }<br>
>         +}<br>
><br>
>          static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5,<br>
>         6 };<br>
>          static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 };<br>
>         diff --git a/src/mesa/main/format_utils.h<br>
>         b/src/mesa/main/format_utils.h<br>
>         index 010d137..4d348cc 100644<br>
>         --- a/src/mesa/main/format_utils.h<br>
>         +++ b/src/mesa/main/format_utils.h<br>
>         @@ -33,6 +33,11 @@<br>
><br>
>          #include "imports.h"<br>
><br>
>         +extern mesa_array_format RGBA8888_FLOAT;<br>
>         +extern mesa_array_format RGBA8888_UBYTE;<br>
>         +extern mesa_array_format RGBA8888_UINT;<br>
>         +extern mesa_array_format RGBA8888_INT;<br>
>         +<br>
>          /* Only guaranteed to work for BITS <= 32 */<br>
>          #define MAX_UINT(BITS) ((BITS) == 32 ? UINT32_MAX : ((1u <<<br>
>         (BITS)) - 1))<br>
>          #define MAX_INT(BITS) ((int)MAX_UINT((BITS) - 1))<br>
>         @@ -147,4 +152,9 @@ _mesa_swizzle_and_convert(void *dst,<br>
>         GLenum dst_type, int num_dst_channels,<br>
>                                    const void *src, GLenum src_type,<br>
>         int num_src_channels,<br>
>                                    const uint8_t swizzle[4], bool<br>
>         normalized, int count);<br>
><br>
>         +void<br>
>         +_mesa_format_convert(void *void_dst, uint32_t dst_format,<br>
>         size_t dst_stride,<br>
>         +                     void *void_src, uint32_t src_format,<br>
>         size_t src_stride,<br>
>         +                     size_t width, size_t height);<br>
>         +<br>
>          #endif<br>
>         diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h<br>
>         index bba5bae..7a792d4 100644<br>
>         --- a/src/mesa/main/formats.h<br>
>         +++ b/src/mesa/main/formats.h<br>
>         @@ -81,7 +81,7 @@ enum {<br>
>             MESA_FORMAT_SWIZZLE_NONE = 6,<br>
>          };<br>
><br>
>         -enum  mesa_array_format_datatype {<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>
>         @@ -90,11 +90,12 @@ enum  mesa_array_format_datatype {<br>
>             MESA_ARRAY_FORMAT_TYPE_INT = 0x6,<br>
>             MESA_ARRAY_FORMAT_TYPE_HALF = 0xd,<br>
>             MESA_ARRAY_FORMAT_TYPE_FLOAT = 0xe,<br>
>         -<br>
>         -   MESA_ARRAY_FORMAT_TYPE_IS_SIGNED = 0x4,<br>
>         -   MESA_ARRAY_FORMAT_TYPE_IS_FLOAT = 0x8,<br>
>          };<br>
><br>
>         +#define MESA_ARRAY_FORMAT_TYPE_IS_SIGNED 0x4<br>
>         +#define MESA_ARRAY_FORMAT_TYPE_IS_FLOAT 0x8<br>
>         +#define MESA_ARRAY_FORMAT_BIT 0x80000000<br>
>         +<br>
>          typedef union {<br>
>             struct {<br>
>                enum mesa_array_format_datatype type:4;<br>
>         @@ -130,6 +131,12 @@ _mesa_ilog2(unsigned x)<br>
>             (((SIGNED)    << 2 ) & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) |<br>
>         \<br>
>             (((IS_FLOAT)  << 3 ) & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT)<br>
><br>
>         +static inline int<br>
>         +_mesa_array_format_datatype_size(enum<br>
>         mesa_array_format_datatype type)<br>
>         +{<br>
>         +   return 1 << (type & 0x3);<br>
>         +}<br>
>         +<br>
>          /**<br>
>           * Mesa texture/renderbuffer image formats.<br>
>           */<br>
><br>
><br>
> Let's squash these changes into the pach where we first introduce<br>
> array formats.<br>
<br>
</div></div>Ok.<br>
<div class="HOEnZb"><div class="h5"><br>
><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>
><br>
><br>
<br>
<br>
</div></div></blockquote></div><br></div></div>