[Mesa-dev] [PATCH] mesa: Fix element count for byte-swaps in texstore, readpix and texgetimage
Ian Romanick
idr at freedesktop.org
Fri Feb 13 10:19:48 PST 2015
Also... please tag the commit with
Cc: "10.5" <mesa-stable at lists.freedesktop.org>
On 02/13/2015 03:56 AM, Iago Toral Quiroga wrote:
> Some old format conversion code in pack.c implemented byte-swapping like this:
>
> GLint comps = _mesa_components_in_format(dstFormat);
> GLint swapSize = _mesa_sizeof_packed_type(dstType);
> if (swapSize == 2)
> _mesa_swap2((GLushort *) dstAddr, n * comps);
> else if (swapSize == 4)
> _mesa_swap4((GLuint *) dstAddr, n * comps);
>
> where n is the pixel count. But this is incorrect for packed formats,
> where _mesa_sizeof_packed_type is already returning the size of a pixel
> instead of the size of a single component, so multiplying this by the
> number of components in the format results in a larger element count
> for _mesa_swap than we want.
>
> Unfortunately, we followed the same implementation for byte-swapping
> in the rewrite of the format conversion code for texstore, readpixels
> and texgetimage.
>
> This patch computes the correct element counts for _mesa_swap calls
> by computing the bytes per pixel in the image and dividing that by the
> swap size to obtain the number of swaps required per pixel. Then multiplies
> that by the number of pixels in the image to obtain the swap count that
> we need to use.
>
> Also, when handling byte-swapping in texstore_rgba, we were ignoring
> the image's depth. This patch fixes this too.
> ---
> src/mesa/main/readpix.c | 13 ++++++++-----
> src/mesa/main/texgetimage.c | 13 ++++++++-----
> src/mesa/main/texstore.c | 14 +++++++++-----
> 3 files changed, 25 insertions(+), 15 deletions(-)
>
> diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
> index 85f900d..ca4b943 100644
> --- a/src/mesa/main/readpix.c
> +++ b/src/mesa/main/readpix.c
> @@ -605,12 +605,15 @@ read_rgba_pixels( struct gl_context *ctx,
> done_swap:
> /* Handle byte swapping if required */
> if (packing->SwapBytes) {
> - int components = _mesa_components_in_format(format);
> GLint swapSize = _mesa_sizeof_packed_type(type);
> - if (swapSize == 2)
> - _mesa_swap2((GLushort *) dst, width * height * components);
> - else if (swapSize == 4)
> - _mesa_swap4((GLuint *) dst, width * height * components);
> + 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);
> + }
> }
>
> done_unmap:
> diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
> index ee465e6..405f085 100644
> --- a/src/mesa/main/texgetimage.c
> +++ b/src/mesa/main/texgetimage.c
> @@ -511,12 +511,15 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
> do_swap:
> /* Handle byte swapping if required */
> if (ctx->Pack.SwapBytes) {
> - int components = _mesa_components_in_format(format);
> GLint swapSize = _mesa_sizeof_packed_type(type);
> - if (swapSize == 2)
> - _mesa_swap2((GLushort *) dest, width * height * components);
> - else if (swapSize == 4)
> - _mesa_swap4((GLuint *) dest, width * height * components);
> + 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);
> + }
> }
>
> /* Unmap the src texture buffer */
> diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
> index 4d32659..227693d 100644
> --- a/src/mesa/main/texstore.c
> +++ b/src/mesa/main/texstore.c
> @@ -721,15 +721,19 @@ texstore_rgba(TEXSTORE_PARAMS)
> */
> GLint swapSize = _mesa_sizeof_packed_type(srcType);
> if (swapSize == 2 || swapSize == 4) {
> - int components = _mesa_components_in_format(srcFormat);
> - int elementCount = srcWidth * srcHeight * components;
> - tempImage = malloc(elementCount * swapSize);
> + int bytesPerPixel = _mesa_bytes_per_pixel(srcFormat, srcType);
> + assert(bytesPerPixel % swapSize == 0);
> + int swapsPerPixel = bytesPerPixel / swapSize;
> + int elementCount = srcWidth * srcHeight * srcDepth;
> + tempImage = malloc(elementCount * bytesPerPixel);
> if (!tempImage)
> return GL_FALSE;
> if (swapSize == 2)
> - _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, elementCount);
> + _mesa_swap2_copy(tempImage, (GLushort *) srcAddr,
> + elementCount * swapsPerPixel);
> else
> - _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, elementCount);
> + _mesa_swap4_copy(tempImage, (GLuint *) srcAddr,
> + elementCount * swapsPerPixel);
> srcAddr = tempImage;
> }
> }
>
More information about the mesa-dev
mailing list