[Mesa-dev] [PATCH 06/29] mesa: Avoid pack/unpack fast paths if base internal format != base format

Iago Toral itoral at igalia.com
Wed Nov 19 23:58:19 PST 2014


On Wed, 2014-11-19 at 11:57 -0800, Jason Ekstrand wrote:
> A couple of general comments on this patch:
> 
> 
> 1) The prerequisites should be moved to before the first patch in the
> series and it should be squashed into the patch that introduces the
> function.  There are one or two more patches which also modify it and
> those should also be squashed in.

Ok.

> 
> 2) I wonder if giving _mesa_format_convert an internal swizzle
> wouldn't be better than a destination internal format.  There are a
> couple of reasons for this:
> 
>     a) It's more general.  If it doesn't cost us anything extra to do
> it that way, we might as well.

I think that would only work directly for conversions between array
formats, but what if we have, for example, a texture upload from RGB565
to a Luminance format (so that we get an RGBA base format)? that would
not go though _mesa_swizzle_and_convert and would require to unpack to
RGBA and then pack to the dst... and unless the client has provided the
dst format as an array format that won't use _mesa_swizzle_and_convert
either. That should not be a problem when the calls to
_mesa_format_convert come from things like glTexImage or glReadPixels,
since in these cases the compute the dst format from a GL type and if it
is an array format we should get that, but in other cases that might not
be the case...

>     b) It removes the GL enum dependency from the _mesa_format_convert
>     c) I think this implementation misses the case where we download a
> texture that is storred in a different format than its base format.
> For instance, if you are downloading a GL_RGB texture as GL_RGBA but
> it's storred as GL_RGBA.  I think with the current implementaion,
> you'll get the junk in the alpha component of the texture's backing
> storage instead of a constant alpha value of 1.

That's correct. In the implementation of readpixels and getteximage we
had to rebase the results in some cases to account for that.

Iago

> 
> On Tue, Nov 18, 2014 at 1:23 AM, Iago Toral Quiroga
> <itoral at igalia.com> wrote:
>         In general, if the dst base internal format and the selected
>         dst format are
>         different we can't be sure that directly packing or unpacking
>         to the destination
>         format will produce correct results. In these cases we
>         probably want to fall
>         back to other paths (like mesa_swizzle_and_convert) that can
>         handle these
>         situations better.
>         
>         An example of this includes a luminance internal format for
>         which the driver
>         decided to use something like BGRA. In these case, unpacking
>         to BGRA won't
>         match the requirements of the luminance internal format.
>         
>         In the future we may want to allow these fast paths for
>         specific cases
>         where we know the direct pack/unpack functions will do the
>         right thing.
>         ---
>          src/mesa/main/format_utils.c | 137
>         +++++++++++++++++++++++--------------------
>          1 file changed, 72 insertions(+), 65 deletions(-)
>         
>         diff --git a/src/mesa/main/format_utils.c
>         b/src/mesa/main/format_utils.c
>         index 5964689..34c90d9 100644
>         --- a/src/mesa/main/format_utils.c
>         +++ b/src/mesa/main/format_utils.c
>         @@ -331,65 +331,82 @@ _mesa_format_convert(void *void_dst,
>         uint32_t dst_format, size_t dst_stride,
>                dst_array_format.as_uint =
>         _mesa_format_to_array_format(dst_format);
>             }
>         
>         -   /* Handle the cases where we can directly unpack */
>         -   if (!(src_format & MESA_ARRAY_FORMAT_BIT)) {
>         -      if (dst_array_format.as_uint == RGBA8888_FLOAT.as_uint)
>         {
>         -         for (row = 0; row < height; ++row) {
>         -            _mesa_unpack_rgba_row(src_format, width,
>         -                                  src, (float (*)[4])dst);
>         -            src += src_stride;
>         -            dst += dst_stride;
>         -         }
>         -         return;
>         -      } else if (dst_array_format.as_uint ==
>         RGBA8888_UBYTE.as_uint &&
>         -                 !_mesa_is_format_integer_color(src_format))
>         {
>         -         for (row = 0; row < height; ++row) {
>         -            _mesa_unpack_ubyte_rgba_row(src_format, width,
>         -                                        src, (uint8_t
>         (*)[4])dst);
>         -            src += src_stride;
>         -            dst += dst_stride;
>         -         }
>         -         return;
>         -      } else if (dst_array_format.as_uint ==
>         RGBA8888_UINT.as_uint &&
>         -                 _mesa_is_format_integer_color(src_format)) {
>         -         for (row = 0; row < height; ++row) {
>         -            _mesa_unpack_uint_rgba_row(src_format, width,
>         -                                       src, (uint32_t
>         (*)[4])dst);
>         -            src += src_stride;
>         -            dst += dst_stride;
>         +   /* First we see if we can implement the conversion with a
>         direct pack
>         +    * or unpack.
>         +    *
>         +    * In this case we want to be careful when the dst base
>         format and the
>         +    * dst format do not match. In these cases a simple
>         pack/unpack to the
>         +    * dst format from the src format may not match the
>         semantic requirements
>         +    * of the internal base format. For now we decide to be
>         safe and avoid
>         +    * this path in these scenarios but in the future we may
>         want to enable
>         +    * it for specific combinations that are known to work.
>         +    */
>         +   mesa_format dst_mesa_format;
>         +   if (dst_format & MESA_ARRAY_FORMAT_BIT)
>         +      dst_mesa_format =
>         _mesa_format_from_array_format(dst_format);
>         +   else
>         +      dst_mesa_format = dst_format;
>         +   if (_mesa_get_format_base_format(dst_mesa_format) ==
>         dst_internal_format) {
>         +      /* Handle the cases where we can directly unpack */
>         +      if (!(src_format & MESA_ARRAY_FORMAT_BIT)) {
>         +         if (dst_array_format.as_uint ==
>         RGBA8888_FLOAT.as_uint) {
>         +            for (row = 0; row < height; ++row) {
>         +               _mesa_unpack_rgba_row(src_format, width,
>         +                                     src, (float (*)[4])dst);
>         +               src += src_stride;
>         +               dst += dst_stride;
>         +            }
>         +            return;
>         +         } else if (dst_array_format.as_uint ==
>         RGBA8888_UBYTE.as_uint &&
>         +                    !
>         _mesa_is_format_integer_color(src_format)) {
>         +            for (row = 0; row < height; ++row) {
>         +               _mesa_unpack_ubyte_rgba_row(src_format, width,
>         +                                           src, (uint8_t
>         (*)[4])dst);
>         +               src += src_stride;
>         +               dst += dst_stride;
>         +            }
>         +            return;
>         +         } else if (dst_array_format.as_uint ==
>         RGBA8888_UINT.as_uint &&
>         +
>         _mesa_is_format_integer_color(src_format)) {
>         +            for (row = 0; row < height; ++row) {
>         +               _mesa_unpack_uint_rgba_row(src_format, width,
>         +                                          src, (uint32_t
>         (*)[4])dst);
>         +               src += src_stride;
>         +               dst += dst_stride;
>         +            }
>         +            return;
>                   }
>         -         return;
>                }
>         -   }
>         
>         -   /* Handle the cases where we can directly pack */
>         -   if (!(dst_format & MESA_ARRAY_FORMAT_BIT)) {
>         -      if (src_array_format.as_uint == RGBA8888_FLOAT.as_uint)
>         {
>         -         for (row = 0; row < height; ++row) {
>         -            _mesa_pack_float_rgba_row(dst_format, width,
>         -                                      (const float
>         (*)[4])src, dst);
>         -            src += src_stride;
>         -            dst += dst_stride;
>         -         }
>         -         return;
>         -      } else if (src_array_format.as_uint ==
>         RGBA8888_UBYTE.as_uint &&
>         -                 !_mesa_is_format_integer_color(dst_format))
>         {
>         -         for (row = 0; row < height; ++row) {
>         -            _mesa_pack_ubyte_rgba_row(dst_format, width,
>         -                                      (const uint8_t
>         (*)[4])src, dst);
>         -            src += src_stride;
>         -            dst += dst_stride;
>         -         }
>         -         return;
>         -      } else if (src_array_format.as_uint ==
>         RGBA8888_UINT.as_uint &&
>         -                 _mesa_is_format_integer_color(dst_format)) {
>         -         for (row = 0; row < height; ++row) {
>         -            _mesa_pack_uint_rgba_row(dst_format, width,
>         -                                     (const uint32_t
>         (*)[4])src, dst);
>         -            src += src_stride;
>         -            dst += dst_stride;
>         +      /* Handle the cases where we can directly pack. */
>         +      if (!(dst_format & MESA_ARRAY_FORMAT_BIT)) {
>         +         if (src_array_format.as_uint ==
>         RGBA8888_FLOAT.as_uint) {
>         +            for (row = 0; row < height; ++row) {
>         +               _mesa_pack_float_rgba_row(dst_format, width,
>         +                                         (const float
>         (*)[4])src, dst);
>         +               src += src_stride;
>         +               dst += dst_stride;
>         +            }
>         +            return;
>         +         } else if (src_array_format.as_uint ==
>         RGBA8888_UBYTE.as_uint &&
>         +                    !
>         _mesa_is_format_integer_color(dst_format)) {
>         +            for (row = 0; row < height; ++row) {
>         +               _mesa_pack_ubyte_rgba_row(dst_format, width,
>         +                                         (const uint8_t
>         (*)[4])src, dst);
>         +               src += src_stride;
>         +               dst += dst_stride;
>         +            }
>         +            return;
>         +         } else if (src_array_format.as_uint ==
>         RGBA8888_UINT.as_uint &&
>         +
>         _mesa_is_format_integer_color(dst_format)) {
>         +            for (row = 0; row < height; ++row) {
>         +               _mesa_pack_uint_rgba_row(dst_format, width,
>         +                                        (const uint32_t
>         (*)[4])src, dst);
>         +               src += src_stride;
>         +               dst += dst_stride;
>         +            }
>         +            return;
>                   }
>         -         return;
>                }
>             }
>         
>         @@ -431,11 +448,6 @@ _mesa_format_convert(void *void_dst,
>         uint32_t dst_format, size_t dst_stride,
>                 * by computing the swizzle transform
>         src->rgba->base->rgba->dst instead
>                 * of src->rgba->dst.
>                 */
>         -      mesa_format dst_mesa_format;
>         -      if (dst_format & MESA_ARRAY_FORMAT_BIT)
>         -         dst_mesa_format =
>         _mesa_format_from_array_format(dst_format);
>         -      else
>         -         dst_mesa_format = dst_format;
>                if (dst_internal_format !=
>         _mesa_get_format_base_format(dst_mesa_format)) {
>                   /* Compute src2rgba as src->rgba->base->rgba */
>                   uint8_t rgba2base[4], base2rgba[4], swizzle[4];
>         @@ -580,11 +592,6 @@ _mesa_format_convert(void *void_dst,
>         uint32_t dst_format, size_t dst_stride,
>                    */
>                   GLubyte rgba2base[4], base2rgba[4], map[4];
>                   bool need_convert = false;
>         -         mesa_format dst_mesa_format;
>         -         if (dst_format & MESA_ARRAY_FORMAT_BIT)
>         -            dst_mesa_format =
>         _mesa_format_from_array_format(dst_format);
>         -         else
>         -            dst_mesa_format = dst_format;
>                   if (dst_internal_format !=
>                       _mesa_get_format_base_format(dst_mesa_format)) {
>                      _mesa_compute_component_mapping(GL_RGBA,
>         dst_internal_format,
>         --
>         1.9.1
>         
>         _______________________________________________
>         mesa-dev mailing list
>         mesa-dev at lists.freedesktop.org
>         http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 
> 




More information about the mesa-dev mailing list