From d9534e4785b26a0c65153dad934ab8a03723d89c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 25 Aug 2015 14:36:01 +1000 Subject: [PATCH] mesa: fix SwapBytes handling in numerous places In a number of places the SwapBytes handling didn't handle cases with GL_(UN)PACK_ALIGNMENT set and 7 byte width cases aligned to 8 bytes. This adds a common routine to swap bytes a 2D image and uses this code in: texture storage texture get readpixels swrast drawpixels. [airlied: updated with Brian's nitpicks]. Cc: "11.0" Reviewed-by: Brian Paul Signed-off-by: Dave Airlie (cherry picked from commit 0ad3a475ef81dad3baf607d749b91dfa1700ca23) --- src/mesa/main/image.c | 58 +++++++++++++++++++++++++++++++++++++++++---- src/mesa/main/image.h | 20 ++++++---------- src/mesa/main/readpix.c | 11 ++------- src/mesa/main/texgetimage.c | 14 +++-------- src/mesa/main/texstore.c | 28 +++++++++++++--------- src/mesa/swrast/s_drawpix.c | 14 +++++------ 6 files changed, 89 insertions(+), 56 deletions(-) diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 711a19062a9..e79e3e68eac 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -49,8 +49,8 @@ * \param src the array with the source data we want to byte-swap. * \param n number of words. */ -void -_mesa_swap2_copy( GLushort *dst, GLushort *src, GLuint n ) +static void +swap2_copy( GLushort *dst, GLushort *src, GLuint n ) { GLuint i; for (i = 0; i < n; i++) { @@ -58,7 +58,11 @@ _mesa_swap2_copy( GLushort *dst, GLushort *src, GLuint n ) } } - +void +_mesa_swap2(GLushort *p, GLuint n) +{ + swap2_copy(p, p, n); +} /* * Flip the order of the 4 bytes in each word in the given array (src) and @@ -69,8 +73,8 @@ _mesa_swap2_copy( GLushort *dst, GLushort *src, GLuint n ) * \param src the array with the source data we want to byte-swap. * \param n number of words. */ -void -_mesa_swap4_copy( GLuint *dst, GLuint *src, GLuint n ) +static void +swap4_copy( GLuint *dst, GLuint *src, GLuint n ) { GLuint i, a, b; for (i = 0; i < n; i++) { @@ -83,6 +87,11 @@ _mesa_swap4_copy( GLuint *dst, GLuint *src, GLuint n ) } } +void +_mesa_swap4(GLuint *p, GLuint n) +{ + swap4_copy(p, p, n); +} /** * Return the byte offset of a specific pixel in an image (1D, 2D or 3D). @@ -958,3 +967,42 @@ _mesa_clip_blit(struct gl_context *ctx, return GL_TRUE; } + +/** + * Swap the bytes in a 2D image. + * + * using the packing information this swaps the bytes + * according to the format and type of data being input. + * It takes into a/c various packing parameters like + * Alignment and RowLength. + */ +void +_mesa_swap_bytes_2d_image(GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + GLsizei width, GLsizei height, + GLvoid *dst, const GLvoid *src) +{ + GLint swapSize = _mesa_sizeof_packed_type(type); + + assert(packing->SwapBytes); + + if (swapSize == 2 || swapSize == 4) { + int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize; + int stride = _mesa_image_row_stride(packing, width, format, type); + int row; + uint8_t *dstrow; + const uint8_t *srcrow; + assert(swapsPerPixel > 0); + assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0); + dstrow = dst; + srcrow = src; + for (row = 0; row < height; row++) { + if (swapSize == 2) + swap2_copy((GLushort *)dstrow, (GLushort *)srcrow, width * swapsPerPixel); + else if (swapSize == 4) + swap4_copy((GLuint *)dstrow, (GLuint *)srcrow, width * swapsPerPixel); + dstrow += stride; + srcrow += stride; + } + } +} diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h index 501586bfbd3..b5075be4b86 100644 --- a/src/mesa/main/image.h +++ b/src/mesa/main/image.h @@ -35,22 +35,11 @@ struct gl_pixelstore_attrib; struct gl_framebuffer; extern void -_mesa_swap2_copy(GLushort *dst, GLushort *src, GLuint n); +_mesa_swap2(GLushort *p, GLuint n); extern void -_mesa_swap4_copy(GLuint *dst, GLuint *src, GLuint n); +_mesa_swap4(GLuint *p, GLuint n); -static inline void -_mesa_swap2(GLushort *p, GLuint n) -{ - _mesa_swap2_copy(p, p, n); -} - -static inline void -_mesa_swap4(GLuint *p, GLuint n) -{ - _mesa_swap4_copy(p, p, n); -} extern GLintptr _mesa_image_offset( GLuint dimensions, @@ -146,5 +135,10 @@ _mesa_clip_blit(struct gl_context *ctx, GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1, GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1); +void +_mesa_swap_bytes_2d_image(GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + GLsizei width, GLsizei height, + GLvoid *dst, const GLvoid *src); #endif diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c index d826ecfc3d5..7c37fd47fdc 100644 --- a/src/mesa/main/readpix.c +++ b/src/mesa/main/readpix.c @@ -613,15 +613,8 @@ read_rgba_pixels( struct gl_context *ctx, done_swap: /* Handle byte swapping if required */ if (packing->SwapBytes) { - GLint swapSize = _mesa_sizeof_packed_type(type); - if (swapSize == 2 || swapSize == 4) { - int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize; - assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0); - if (swapSize == 2) - _mesa_swap2((GLushort *) dst, width * height * swapsPerPixel); - else if (swapSize == 4) - _mesa_swap4((GLuint *) dst, width * height * swapsPerPixel); - } + _mesa_swap_bytes_2d_image(format, type, packing, + width, height, dst, dst); } done_unmap: diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 56f5de12f99..5eb7bf5c94d 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -557,17 +557,9 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, do_swap: /* Handle byte swapping if required */ - if (ctx->Pack.SwapBytes) { - GLint swapSize = _mesa_sizeof_packed_type(type); - if (swapSize == 2 || swapSize == 4) { - int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize; - assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0); - if (swapSize == 2) - _mesa_swap2((GLushort *) dest, width * height * swapsPerPixel); - else if (swapSize == 4) - _mesa_swap4((GLuint *) dest, width * height * swapsPerPixel); - } - } + if (ctx->Pack.SwapBytes) + _mesa_swap_bytes_2d_image(format, type, &ctx->Pack, + width, height, dest, dest); /* Unmap the src texture buffer */ ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img); diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 777466469f8..ca0d17f342f 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -727,19 +727,25 @@ texstore_rgba(TEXSTORE_PARAMS) */ GLint swapSize = _mesa_sizeof_packed_type(srcType); if (swapSize == 2 || swapSize == 4) { - int bytesPerPixel = _mesa_bytes_per_pixel(srcFormat, srcType); - int swapsPerPixel = bytesPerPixel / swapSize; - int elementCount = srcWidth * srcHeight * srcDepth; - assert(bytesPerPixel % swapSize == 0); - tempImage = malloc(elementCount * bytesPerPixel); + int imageStride = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, srcType); + int bufferSize = imageStride * srcDepth; + int layer; + const uint8_t *src; + uint8_t *dst; + + tempImage = malloc(bufferSize); if (!tempImage) return GL_FALSE; - if (swapSize == 2) - _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, - elementCount * swapsPerPixel); - else - _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, - elementCount * swapsPerPixel); + src = srcAddr; + dst = tempImage; + for (layer = 0; layer < srcDepth; layer++) { + _mesa_swap_bytes_2d_image(srcFormat, srcType, + srcPacking, + srcWidth, srcHeight, + dst, src); + src += imageStride; + dst += imageStride; + } srcAddr = tempImage; } } diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index dc6827ede9f..53997f14d8b 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -481,17 +481,17 @@ draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y, */ GLint swapSize = _mesa_sizeof_packed_type(type); if (swapSize == 2 || swapSize == 4) { - int components = _mesa_components_in_format(format); - int elementCount = width * height * components; - tempImage = malloc(elementCount * swapSize); + int imageStride = _mesa_image_image_stride(unpack, width, height, format, type); + + tempImage = malloc(imageStride); if (!tempImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); return; } - if (swapSize == 2) - _mesa_swap2_copy(tempImage, (GLushort *) pixels, elementCount); - else - _mesa_swap4_copy(tempImage, (GLuint *) pixels, elementCount); + + _mesa_swap_bytes_2d_image(format, type, unpack, + width, height, tempImage, pixels); + pixels = tempImage; } } -- 2.11.0