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" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Brian Paul <brianp@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie
2015-08-25 14:36:01 +10:00
parent 60aea30115
commit 0ad3a475ef
6 changed files with 89 additions and 56 deletions

View File

@@ -49,8 +49,8 @@
* \param src the array with the source data we want to byte-swap. * \param src the array with the source data we want to byte-swap.
* \param n number of words. * \param n number of words.
*/ */
void static void
_mesa_swap2_copy( GLushort *dst, GLushort *src, GLuint n ) swap2_copy( GLushort *dst, GLushort *src, GLuint n )
{ {
GLuint i; GLuint i;
for (i = 0; i < n; 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 * 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 src the array with the source data we want to byte-swap.
* \param n number of words. * \param n number of words.
*/ */
void static void
_mesa_swap4_copy( GLuint *dst, GLuint *src, GLuint n ) swap4_copy( GLuint *dst, GLuint *src, GLuint n )
{ {
GLuint i, a, b; GLuint i, a, b;
for (i = 0; i < n; i++) { 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). * 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; 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;
}
}
}

View File

@@ -35,22 +35,11 @@ struct gl_pixelstore_attrib;
struct gl_framebuffer; struct gl_framebuffer;
extern void extern void
_mesa_swap2_copy(GLushort *dst, GLushort *src, GLuint n); _mesa_swap2(GLushort *p, GLuint n);
extern void 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 extern GLintptr
_mesa_image_offset( GLuint dimensions, _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 *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1); 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 #endif

View File

@@ -613,15 +613,8 @@ read_rgba_pixels( struct gl_context *ctx,
done_swap: done_swap:
/* Handle byte swapping if required */ /* Handle byte swapping if required */
if (packing->SwapBytes) { if (packing->SwapBytes) {
GLint swapSize = _mesa_sizeof_packed_type(type); _mesa_swap_bytes_2d_image(format, type, packing,
if (swapSize == 2 || swapSize == 4) { width, height, dst, dst);
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);
}
} }
done_unmap: done_unmap:

View File

@@ -557,17 +557,9 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
do_swap: do_swap:
/* Handle byte swapping if required */ /* Handle byte swapping if required */
if (ctx->Pack.SwapBytes) { if (ctx->Pack.SwapBytes)
GLint swapSize = _mesa_sizeof_packed_type(type); _mesa_swap_bytes_2d_image(format, type, &ctx->Pack,
if (swapSize == 2 || swapSize == 4) { width, height, dest, dest);
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);
}
}
/* Unmap the src texture buffer */ /* Unmap the src texture buffer */
ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img); ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img);

View File

@@ -727,19 +727,25 @@ texstore_rgba(TEXSTORE_PARAMS)
*/ */
GLint swapSize = _mesa_sizeof_packed_type(srcType); GLint swapSize = _mesa_sizeof_packed_type(srcType);
if (swapSize == 2 || swapSize == 4) { if (swapSize == 2 || swapSize == 4) {
int bytesPerPixel = _mesa_bytes_per_pixel(srcFormat, srcType); int imageStride = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, srcType);
int swapsPerPixel = bytesPerPixel / swapSize; int bufferSize = imageStride * srcDepth;
int elementCount = srcWidth * srcHeight * srcDepth; int layer;
assert(bytesPerPixel % swapSize == 0); const uint8_t *src;
tempImage = malloc(elementCount * bytesPerPixel); uint8_t *dst;
tempImage = malloc(bufferSize);
if (!tempImage) if (!tempImage)
return GL_FALSE; return GL_FALSE;
if (swapSize == 2) src = srcAddr;
_mesa_swap2_copy(tempImage, (GLushort *) srcAddr, dst = tempImage;
elementCount * swapsPerPixel); for (layer = 0; layer < srcDepth; layer++) {
else _mesa_swap_bytes_2d_image(srcFormat, srcType,
_mesa_swap4_copy(tempImage, (GLuint *) srcAddr, srcPacking,
elementCount * swapsPerPixel); srcWidth, srcHeight,
dst, src);
src += imageStride;
dst += imageStride;
}
srcAddr = tempImage; srcAddr = tempImage;
} }
} }

View File

@@ -481,17 +481,17 @@ draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y,
*/ */
GLint swapSize = _mesa_sizeof_packed_type(type); GLint swapSize = _mesa_sizeof_packed_type(type);
if (swapSize == 2 || swapSize == 4) { if (swapSize == 2 || swapSize == 4) {
int components = _mesa_components_in_format(format); int imageStride = _mesa_image_image_stride(unpack, width, height, format, type);
int elementCount = width * height * components;
tempImage = malloc(elementCount * swapSize); tempImage = malloc(imageStride);
if (!tempImage) { if (!tempImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
return; return;
} }
if (swapSize == 2)
_mesa_swap2_copy(tempImage, (GLushort *) pixels, elementCount); _mesa_swap_bytes_2d_image(format, type, unpack,
else width, height, tempImage, pixels);
_mesa_swap4_copy(tempImage, (GLuint *) pixels, elementCount);
pixels = tempImage; pixels = tempImage;
} }
} }