[Mesa-dev] [PATCH 09/12] main/texstore: Use _mesa_swizzle_and_convert when possible

Brian Paul brianp at vmware.com
Fri Jul 18 08:19:00 PDT 2014


On 07/17/2014 12:04 PM, Jason Ekstrand wrote:
> This should be both faster and more accurate than our general slow-path of
> converting everything to float.
>
> Signed-off-by: Jason Ekstrand <jason.ekstrand at intel.com>
> ---
>   src/mesa/main/texstore.c | 179 +++++++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 164 insertions(+), 15 deletions(-)
>
> diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
> index e1f2284..13fb3a8 100644
> --- a/src/mesa/main/texstore.c
> +++ b/src/mesa/main/texstore.c
> @@ -55,6 +55,7 @@
>   #include "bufferobj.h"
>   #include "colormac.h"
>   #include "format_pack.h"
> +#include "format_utils.h"
>   #include "image.h"
>   #include "macros.h"
>   #include "mipmap.h"
> @@ -233,21 +234,44 @@ static int
>   get_map_idx(GLenum value)
>   {
>      switch (value) {
> -   case GL_LUMINANCE: return IDX_LUMINANCE;
> -   case GL_ALPHA: return IDX_ALPHA;
> -   case GL_INTENSITY: return IDX_INTENSITY;
> -   case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
> -   case GL_RGB: return IDX_RGB;
> -   case GL_RGBA: return IDX_RGBA;
> -   case GL_RED: return IDX_RED;
> -   case GL_GREEN: return IDX_GREEN;
> -   case GL_BLUE: return IDX_BLUE;
> -   case GL_BGR: return IDX_BGR;
> -   case GL_BGRA: return IDX_BGRA;
> -   case GL_ABGR_EXT: return IDX_ABGR;
> -   case GL_RG: return IDX_RG;
> +   case GL_LUMINANCE:
> +   case GL_LUMINANCE_INTEGER_EXT:
> +      return IDX_LUMINANCE;
> +   case GL_ALPHA:
> +   case GL_ALPHA_INTEGER:
> +      return IDX_ALPHA;
> +   case GL_INTENSITY:
> +      return IDX_INTENSITY;
> +   case GL_LUMINANCE_ALPHA:
> +   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
> +      return IDX_LUMINANCE_ALPHA;
> +   case GL_RGB:
> +   case GL_RGB_INTEGER:
> +      return IDX_RGB;
> +   case GL_RGBA:
> +   case GL_RGBA_INTEGER:
> +      return IDX_RGBA;
> +   case GL_RED:
> +   case GL_RED_INTEGER:
> +      return IDX_RED;
> +   case GL_GREEN:
> +      return IDX_GREEN;
> +   case GL_BLUE:
> +      return IDX_BLUE;
> +   case GL_BGR:
> +   case GL_BGR_INTEGER:
> +      return IDX_BGR;
> +   case GL_BGRA:
> +   case GL_BGRA_INTEGER:
> +      return IDX_BGRA;
> +   case GL_ABGR_EXT:
> +      return IDX_ABGR;
> +   case GL_RG:
> +   case GL_RG_INTEGER:
> +      return IDX_RG;
>      default:
> -      _mesa_problem(NULL, "Unexpected inFormat");
> +      _mesa_problem(NULL, "Unexpected inFormat %s",
> +                    _mesa_lookup_enum_by_nr(value));
>         return 0;
>      }
>   }
> @@ -789,6 +813,7 @@ swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
>
>   static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
>   static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
> +static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE };
>
>
>   /**
> @@ -826,6 +851,12 @@ byteswap_mapping( GLboolean swapBytes,
>      switch (srcType) {
>      case GL_BYTE:
>      case GL_UNSIGNED_BYTE:
> +   case GL_SHORT:
> +   case GL_UNSIGNED_SHORT:
> +   case GL_INT:
> +   case GL_UNSIGNED_INT:
> +   case GL_FLOAT:
> +   case GL_HALF_FLOAT:
>         return map_identity;
>      case GL_UNSIGNED_INT_8_8_8_8:
>      case GL_UNSIGNED_INT_8_8_8_8_REV:
> @@ -3621,6 +3652,117 @@ texstore_compressed(TEXSTORE_PARAMS)
>                              srcFormat, srcType, srcAddr, srcPacking);
>   }
>
> +static void
> +invert_swizzle(uint8_t dst[4], const uint8_t src[4])

Please put a comment on this function to explain what it does.  Maybe 
use GLubyte for dst, src since that's the type of the arguments below.



> +{
> +   int i, j;
> +
> +   dst[0] = MESA_FORMAT_SWIZZLE_NONE;
> +   dst[1] = MESA_FORMAT_SWIZZLE_NONE;
> +   dst[2] = MESA_FORMAT_SWIZZLE_NONE;
> +   dst[3] = MESA_FORMAT_SWIZZLE_NONE;
> +
> +   for (i = 0; i < 4; ++i)
> +      for (j = 0; j < 4; ++j)
> +         if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE)
> +            dst[i] = j;
> +}
> +
> +static GLboolean
> +texstore_swizzle(TEXSTORE_PARAMS)

Commment on this function too, please.


> +{
> +   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
> +                                                     srcFormat, srcType);
> +   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
> +                                      srcWidth, srcHeight, srcFormat, srcType);
> +   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dims,
> +        srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
> +   const int src_components = _mesa_components_in_format(srcFormat);
> +
> +   GLubyte swizzle[4], rgba2base[6], base2src[6], rgba2dst[4], dst2rgba[4];
> +   const GLubyte *swap;
> +   GLenum dst_type;
> +   int dst_components;
> +   bool is_array, normalized, need_swap;
> +   GLint i, img, row;
> +   const GLubyte *src_row;
> +   GLubyte *dst_row;
> +
> +   is_array = _mesa_format_to_array(dstFormat, &dst_type, &dst_components,
> +                                    rgba2dst, &normalized);
> +
> +   if (!is_array)
> +      return GL_FALSE;
> +
> +   switch (srcType) {
> +   case GL_FLOAT:
> +   case GL_UNSIGNED_BYTE:
> +   case GL_BYTE:
> +   case GL_UNSIGNED_SHORT:
> +   case GL_SHORT:
> +   case GL_UNSIGNED_INT:
> +   case GL_INT:
> +      /* If wa have to swap bytes in a multi-byte datatype, that means

"we"


> +       * we're not doing an array conversion anymore */

Closing */ on next line.

> +      if (srcPacking->SwapBytes)
> +         return GL_FALSE;
> +      need_swap = false;
> +      break;
> +   case GL_UNSIGNED_INT_8_8_8_8:
> +      need_swap = srcPacking->SwapBytes;
> +      if (_mesa_little_endian())
> +         need_swap = !need_swap;
> +      srcType = GL_UNSIGNED_BYTE;
> +      break;
> +   case GL_UNSIGNED_INT_8_8_8_8_REV:
> +      need_swap = srcPacking->SwapBytes;
> +      if (!_mesa_little_endian())
> +         need_swap = !need_swap;
> +      srcType = GL_UNSIGNED_BYTE;
> +      break;
> +   default:
> +      return GL_FALSE;
> +   }
> +   swap = need_swap ? map_3210 : map_identity;
> +
> +   compute_component_mapping(srcFormat, baseInternalFormat, base2src);
> +   compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
> +   invert_swizzle(dst2rgba, rgba2dst);
> +
> +   for (i = 0; i < 4; i++) {
> +      if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE)
> +         swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;
> +      else
> +         swizzle[i] = swap[base2src[rgba2base[dst2rgba[i]]]];
> +   }
> +
> +   /* Is it normalized? */
> +   normalized |= !_mesa_is_enum_format_integer(srcFormat);

I think that would read better as:

    if (!_mesa_is_enum_format_integer(srcFormat))
       normalized = true;


> +
> +   for (img = 0; img < srcDepth; img++) {
> +      if (dstRowStride == srcWidth * dst_components &&
> +          srcRowStride == srcWidth * src_components) {
> +         _mesa_swizzle_and_convert(dstSlices[img], dst_type, dst_components,
> +                                   srcImage, srcType, src_components,
> +                                   swizzle, normalized, srcWidth * srcHeight);
> +      } else {
> +         src_row = srcImage;
> +         dst_row = dstSlices[img];
> +         for (row = 0; row < srcHeight; row++) {
> +            _mesa_swizzle_and_convert(dst_row, dst_type, dst_components,
> +                                      src_row, srcType, src_components,
> +                                      swizzle, normalized, srcWidth);
> +            dst_row += dstRowStride;
> +            src_row += srcRowStride;
> +         }
> +      }
> +      srcImage += srcImageStride;
> +   }
> +
> +   return GL_TRUE;
> +}
> +
> +
>   static GLboolean
>   texstore_rgba(TEXSTORE_PARAMS)
>   {
> @@ -3796,6 +3938,14 @@ texstore_rgba(TEXSTORE_PARAMS)
>         initialized = GL_TRUE;
>      }
>
> +   if (texstore_swizzle(ctx, dims, baseInternalFormat,
> +                        dstFormat,
> +                        dstRowStride, dstSlices,
> +                        srcWidth, srcHeight, srcDepth,
> +                        srcFormat, srcType, srcAddr, srcPacking)) {
> +      return GL_TRUE;
> +   }
> +
>      ASSERT(table[dstFormat]);
>      return table[dstFormat](ctx, dims, baseInternalFormat,
>                              dstFormat, dstRowStride, dstSlices,
> @@ -3873,7 +4023,6 @@ _mesa_texstore_memcpy(TEXSTORE_PARAMS)
>      return GL_TRUE;
>   }
>
> -
>   /**
>    * Store user data into texture memory.
>    * Called via glTex[Sub]Image1/2/3D()
>



More information about the mesa-dev mailing list