[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