[Mesa-dev] [PATCH] mesa: split get_tex_rgba() into compressed/uncompressed versions
Jose Fonseca
jfonseca at vmware.com
Wed Dec 21 03:19:24 PST 2011
Looks good to me.
Jose
----- Original Message -----
> From: Brian Paul <brianp at vmware.com>
>
> This just splits one big function into two smaller ones for better
> readability.
> ---
> src/mesa/main/texgetimage.c | 322
> +++++++++++++++++++++++-------------------
> 1 files changed, 176 insertions(+), 146 deletions(-)
>
> diff --git a/src/mesa/main/texgetimage.c
> b/src/mesa/main/texgetimage.c
> index 3f24187..81863be 100644
> --- a/src/mesa/main/texgetimage.c
> +++ b/src/mesa/main/texgetimage.c
> @@ -216,183 +216,213 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint
> dimensions,
>
>
> /**
> - * glGetTexImage for color formats (RGBA, RGB, alpha, LA, etc).
> - * Compressed textures are handled here as well.
> + * Get a color texture image with decompression.
> */
> static void
> -get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
> - GLenum format, GLenum type, GLvoid *pixels,
> - struct gl_texture_image *texImage)
> +get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions,
> + GLenum format, GLenum type, GLvoid *pixels,
> + struct gl_texture_image *texImage,
> + GLbitfield transferOps)
> {
> /* don't want to apply sRGB -> RGB conversion here so override
> the format */
> - const gl_format texFormat =
> _mesa_get_srgb_format_linear(texImage->TexFormat);
> + const gl_format texFormat =
> + _mesa_get_srgb_format_linear(texImage->TexFormat);
> + const GLenum baseFormat =
> _mesa_get_format_base_format(texFormat);
> const GLuint width = texImage->Width;
> const GLuint height = texImage->Height;
> const GLuint depth = texImage->Depth;
> - const GLenum dataType = _mesa_get_format_datatype(texFormat);
> - const GLenum baseFormat =
> _mesa_get_format_base_format(texFormat);
> - /* Normally, no pixel transfer ops are performed during
> glGetTexImage.
> - * The only possible exception is component clamping to [0,1].
> - */
> - GLbitfield transferOps = 0x0;
> -
> - /* In general, clamping does not apply to glGetTexImage, except
> when
> - * the returned type of the image can't hold negative values.
> - */
> - if (type_needs_clamping(type)) {
> - /* the returned image type can't have negative values */
> - if (dataType == GL_FLOAT ||
> - dataType == GL_SIGNED_NORMALIZED ||
> - format == GL_LUMINANCE ||
> - format == GL_LUMINANCE_ALPHA) {
> - transferOps |= IMAGE_CLAMP_BIT;
> - }
> + GLfloat *tempImage, *srcRow;
> + GLuint row;
> +
> + /* Decompress into temp float buffer, then pack into user buffer
> */
> + tempImage = (GLfloat *) malloc(width * height * depth
> + * 4 * sizeof(GLfloat));
> + if (!tempImage) {
> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
> + return;
> }
>
> - if (_mesa_is_format_compressed(texFormat)) {
> - /* Decompress into temp buffer, then pack into user buffer */
> - GLfloat *tempImage, *srcRow;
> - GLuint row;
> + /* Decompress the texture image - results in 'tempImage' */
> + {
> + GLubyte *srcMap;
> + GLint srcRowStride;
> + GLuint bytes, bw, bh;
>
> - tempImage = (GLfloat *) malloc(texImage->Width *
> texImage->Height *
> - texImage->Depth * 4 *
> sizeof(GLfloat));
> - if (!tempImage) {
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
> - return;
> - }
> + bytes = _mesa_get_format_bytes(texFormat);
> + _mesa_get_format_block_size(texFormat, &bw, &bh);
>
> - /* Decompress the texture image - results in 'tempImage' */
> - {
> - GLubyte *srcMap;
> - GLint srcRowStride;
> - GLuint bytes, bw, bh;
> + ctx->Driver.MapTextureImage(ctx, texImage, 0,
> + 0, 0, width, height,
> + GL_MAP_READ_BIT,
> + &srcMap, &srcRowStride);
> + if (srcMap) {
> + /* XXX This line is a bit of a hack to work around the
> + * mismatch of compressed row strides as returned by
> + * MapTextureImage() vs. what the texture decompression
> code
> + * uses. This will be fixed in the future.
> + */
> + srcRowStride = srcRowStride * bh / bytes;
>
> - bytes = _mesa_get_format_bytes(texImage->TexFormat);
> - _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
> + _mesa_decompress_image(texFormat, width, height,
> + srcMap, srcRowStride, tempImage);
>
> - ctx->Driver.MapTextureImage(ctx, texImage, 0,
> - 0, 0, width, height,
> - GL_MAP_READ_BIT,
> - &srcMap, &srcRowStride);
> + ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
> + }
> + else {
> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
> + }
> + }
>
> - if (srcMap) {
> - /* XXX This line is a bit of a hack to work around the
> - * mismatch of compressed row strides as returned by
> - * MapTextureImage() vs. what the texture decompression
> code
> - * uses. This will be fixed in the future.
> - */
> - srcRowStride = srcRowStride * bh / bytes;
> + if (baseFormat == GL_LUMINANCE ||
> + baseFormat == GL_LUMINANCE_ALPHA) {
> + /* Set green and blue to zero since the pack function here
> will
> + * compute L=R+G+B.
> + */
> + GLuint i;
> + for (i = 0; i < width * height; i++) {
> + tempImage[i * 4 + GCOMP] = tempImage[i * 4 + BCOMP] = 0.0f;
> + }
> + }
>
> - _mesa_decompress_image(texFormat, width, height,
> - srcMap, srcRowStride, tempImage);
> + srcRow = tempImage;
> + for (row = 0; row < height; row++) {
> + void *dest = _mesa_image_address(dimensions, &ctx->Pack,
> pixels,
> + width, height, format, type,
> + 0, row, 0);
>
> - ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
> - }
> - else {
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
> - }
> - }
> + _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4])
> srcRow,
> + format, type, dest, &ctx->Pack,
> transferOps);
> + srcRow += width * 4;
> + }
>
> - if (baseFormat == GL_LUMINANCE ||
> - baseFormat == GL_LUMINANCE_ALPHA) {
> - /* Set green and blue to zero since the pack function here
> will
> - * compute L=R+G+B.
> - */
> - GLuint i;
> - for (i = 0; i < width * height; i++) {
> - tempImage[i * 4 + GCOMP] = tempImage[i * 4 + BCOMP] =
> 0.0f;
> - }
> - }
> + free(tempImage);
> +}
>
> - srcRow = tempImage;
> - for (row = 0; row < height; row++) {
> - void *dest = _mesa_image_address(dimensions, &ctx->Pack,
> pixels,
> - width, height, format,
> type,
> - 0, row, 0);
>
> - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4])
> srcRow,
> - format, type, dest, &ctx->Pack,
> transferOps);
> - srcRow += width * 4;
> - }
> +/**
> + * Get an uncompressed color texture image.
> + */
> +static void
> +get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
> + GLenum format, GLenum type, GLvoid
> *pixels,
> + struct gl_texture_image *texImage,
> + GLbitfield transferOps)
> +{
> + /* don't want to apply sRGB -> RGB conversion here so override
> the format */
> + const gl_format texFormat =
> + _mesa_get_srgb_format_linear(texImage->TexFormat);
> + const GLuint width = texImage->Width;
> + const GLuint height = texImage->Height;
> + const GLuint depth = texImage->Depth;
> + GLuint img, row;
> + GLfloat (*rgba)[4];
>
> - free(tempImage);
> + /* Allocate buffer for one row of texels */
> + rgba = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
> + if (!rgba) {
> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
> + return;
> }
> - else {
> - /* No decompression needed */
> - GLuint img, row;
> - GLfloat (*rgba)[4];
>
> - rgba = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
> - if (!rgba) {
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
> - return;
> - }
> + for (img = 0; img < depth; img++) {
> + GLubyte *srcMap;
> + GLint rowstride;
> +
> + /* map src texture buffer */
> + ctx->Driver.MapTextureImage(ctx, texImage, img,
> + 0, 0, width, height,
> GL_MAP_READ_BIT,
> + &srcMap, &rowstride);
> + if (srcMap) {
> + for (row = 0; row < height; row++) {
> + const GLubyte *src = srcMap + row * rowstride;
> + void *dest = _mesa_image_address(dimensions, &ctx->Pack,
> pixels,
> + width, height, format,
> type,
> + img, row, 0);
>
> - for (img = 0; img < depth; img++) {
> - GLubyte *srcMap;
> - GLint rowstride;
> -
> - /* map src texture buffer */
> - ctx->Driver.MapTextureImage(ctx, texImage, img,
> - 0, 0, width, height,
> GL_MAP_READ_BIT,
> - &srcMap, &rowstride);
> -
> - if (srcMap) {
> - for (row = 0; row < height; row++) {
> - const GLubyte *src = srcMap + row * rowstride;
> - void *dest = _mesa_image_address(dimensions,
> &ctx->Pack, pixels,
> - width, height,
> format, type,
> - img, row, 0);
> -
> - _mesa_unpack_rgba_row(texFormat, width, src, rgba);
> -
> - if (texImage->_BaseFormat == GL_ALPHA) {
> - GLint col;
> - for (col = 0; col < width; col++) {
> - rgba[col][RCOMP] = 0.0F;
> - rgba[col][GCOMP] = 0.0F;
> - rgba[col][BCOMP] = 0.0F;
> - }
> + _mesa_unpack_rgba_row(texFormat, width, src, rgba);
> +
> + if (texImage->_BaseFormat == GL_ALPHA) {
> + GLint col;
> + for (col = 0; col < width; col++) {
> + rgba[col][RCOMP] = 0.0F;
> + rgba[col][GCOMP] = 0.0F;
> + rgba[col][BCOMP] = 0.0F;
> }
> - else if (texImage->_BaseFormat == GL_LUMINANCE) {
> - GLint col;
> - for (col = 0; col < width; col++) {
> - rgba[col][GCOMP] = 0.0F;
> - rgba[col][BCOMP] = 0.0F;
> - rgba[col][ACOMP] = 1.0F;
> - }
> + }
> + else if (texImage->_BaseFormat == GL_LUMINANCE) {
> + GLint col;
> + for (col = 0; col < width; col++) {
> + rgba[col][GCOMP] = 0.0F;
> + rgba[col][BCOMP] = 0.0F;
> + rgba[col][ACOMP] = 1.0F;
> }
> - else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA)
> {
> - GLint col;
> - for (col = 0; col < width; col++) {
> - rgba[col][GCOMP] = 0.0F;
> - rgba[col][BCOMP] = 0.0F;
> - }
> + }
> + else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
> + GLint col;
> + for (col = 0; col < width; col++) {
> + rgba[col][GCOMP] = 0.0F;
> + rgba[col][BCOMP] = 0.0F;
> }
> - else if (texImage->_BaseFormat == GL_INTENSITY) {
> - GLint col;
> - for (col = 0; col < width; col++) {
> - rgba[col][GCOMP] = 0.0F;
> - rgba[col][BCOMP] = 0.0F;
> - rgba[col][ACOMP] = 1.0F;
> - }
> + }
> + else if (texImage->_BaseFormat == GL_INTENSITY) {
> + GLint col;
> + for (col = 0; col < width; col++) {
> + rgba[col][GCOMP] = 0.0F;
> + rgba[col][BCOMP] = 0.0F;
> + rgba[col][ACOMP] = 1.0F;
> }
> -
> - _mesa_pack_rgba_span_float(ctx, width, (GLfloat
> (*)[4]) rgba,
> - format, type, dest,
> - &ctx->Pack, transferOps);
> }
>
> - /* Unmap the src texture buffer */
> - ctx->Driver.UnmapTextureImage(ctx, texImage, img);
> - }
> - else {
> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
> - break;
> + _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4])
> rgba,
> + format, type, dest,
> + &ctx->Pack, transferOps);
> }
> +
> + /* Unmap the src texture buffer */
> + ctx->Driver.UnmapTextureImage(ctx, texImage, img);
> + }
> + else {
> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
> + break;
> }
> + }
> +
> + free(rgba);
> +}
> +
> +
> +/**
> + * glGetTexImage for color formats (RGBA, RGB, alpha, LA, etc).
> + * Compressed textures are handled here as well.
> + */
> +static void
> +get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
> + GLenum format, GLenum type, GLvoid *pixels,
> + struct gl_texture_image *texImage)
> +{
> + const GLenum dataType =
> _mesa_get_format_datatype(texImage->TexFormat);
> + GLbitfield transferOps = 0x0;
>
> - free(rgba);
> + /* In general, clamping does not apply to glGetTexImage, except
> when
> + * the returned type of the image can't hold negative values.
> + */
> + if (type_needs_clamping(type)) {
> + /* the returned image type can't have negative values */
> + if (dataType == GL_FLOAT ||
> + dataType == GL_SIGNED_NORMALIZED ||
> + format == GL_LUMINANCE ||
> + format == GL_LUMINANCE_ALPHA) {
> + transferOps |= IMAGE_CLAMP_BIT;
> + }
> + }
> +
> + if (_mesa_is_format_compressed(texImage->TexFormat)) {
> + get_tex_rgba_compressed(ctx, dimensions, format, type,
> + pixels, texImage, transferOps);
> + }
> + else {
> + get_tex_rgba_uncompressed(ctx, dimensions, format, type,
> + pixels, texImage, transferOps);
> }
> }
>
> --
> 1.7.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
More information about the mesa-dev
mailing list