[Mesa-dev] [PATCH 3/3] mesa: implement mipmap generation for compressed 2D array textures

Jose Fonseca jfonseca at vmware.com
Wed Jul 24 08:52:31 PDT 2013


Series looks alright AFAICT.

Jose

----- Original Message -----
> We weren't looping over all the slices in the array.  The updated
> code should also correctly handle 3D compressed textures too, whenever
> we have that feature.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66850
> 
> NOTE: This is a candidate for the 9.x branches
> Cc: mesa-stable at lists.freedesktop.org
> ---
>  src/mesa/main/mipmap.c |   59
>  +++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 43 insertions(+), 16 deletions(-)
> 
> diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
> index edf7257..5839632 100644
> --- a/src/mesa/main/mipmap.c
> +++ b/src/mesa/main/mipmap.c
> @@ -2020,13 +2020,15 @@ generate_mipmap_compressed(struct gl_context *ctx,
> GLenum target,
>     GLuint level;
>     gl_format temp_format;
>     GLint components;
> -   GLuint temp_src_stride; /* in bytes */
> +   GLuint temp_src_row_stride, temp_src_img_stride; /* in bytes */
>     GLubyte *temp_src = NULL, *temp_dst = NULL;
>     GLenum temp_datatype;
>     GLenum temp_base_format;
> +   GLubyte **temp_src_slices, **temp_dst_slices;
>  
>     /* only two types of compressed textures at this time */
>     assert(texObj->Target == GL_TEXTURE_2D ||
> +	  texObj->Target == GL_TEXTURE_2D_ARRAY ||
>  	  texObj->Target == GL_TEXTURE_CUBE_MAP_ARB);
>  
>     /*
> @@ -2051,15 +2053,24 @@ generate_mipmap_compressed(struct gl_context *ctx,
> GLenum target,
>  
>  
>     /* allocate storage for the temporary, uncompressed image */
> -   /* 20 extra bytes, just be safe when calling last FetchTexel */
> -   temp_src_stride = _mesa_format_row_stride(temp_format, srcImage->Width);
> -   temp_src = malloc(temp_src_stride * srcImage->Height + 20);
> -   if (!temp_src) {
> +   temp_src_row_stride = _mesa_format_row_stride(temp_format,
> srcImage->Width);
> +   temp_src_img_stride = _mesa_format_image_size(temp_format,
> srcImage->Width,
> +                                                 srcImage->Height, 1);
> +   temp_src = malloc(temp_src_img_stride * srcImage->Depth);
> +
> +   /* Allocate storage for arrays of slice pointers */
> +   temp_src_slices = malloc(srcImage->Depth * sizeof(GLubyte *));
> +   temp_dst_slices = malloc(srcImage->Depth * sizeof(GLubyte *));
> +
> +   if (!temp_src || !temp_src_slices || !temp_dst_slices) {
> +      free(temp_src);
> +      free(temp_src_slices);
> +      free(temp_dst_slices);
>        _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
>        return;
>     }
>  
> -   /* decompress base image to the temporary */
> +   /* decompress base image to the temporary src buffer */
>     {
>        /* save pixel packing mode */
>        struct gl_pixelstore_attrib save = ctx->Pack;
> @@ -2075,7 +2086,6 @@ generate_mipmap_compressed(struct gl_context *ctx,
> GLenum target,
>        ctx->Pack = save;
>     }
>  
> -
>     for (level = texObj->BaseLevel; level < maxLevel; level++) {
>        /* generate image[level+1] from image[level] */
>        const struct gl_texture_image *srcImage;
> @@ -2084,7 +2094,8 @@ generate_mipmap_compressed(struct gl_context *ctx,
> GLenum target,
>        GLint dstWidth, dstHeight, dstDepth;
>        GLint border;
>        GLboolean nextLevel;
> -      GLuint temp_dst_stride; /* in bytes */
> +      GLuint temp_dst_row_stride, temp_dst_img_stride; /* in bytes */
> +      GLuint i;
>  
>        /* get src image parameters */
>        srcImage = _mesa_select_tex_image(ctx, texObj, target, level);
> @@ -2100,9 +2111,12 @@ generate_mipmap_compressed(struct gl_context *ctx,
> GLenum target,
>        if (!nextLevel)
>  	 break;
>  
> -      temp_dst_stride = _mesa_format_row_stride(temp_format, dstWidth);
> +      /* Compute dst image strides and alloc memory on first iteration */
> +      temp_dst_row_stride = _mesa_format_row_stride(temp_format, dstWidth);
> +      temp_dst_img_stride = _mesa_format_image_size(temp_format, dstWidth,
> +                                                    dstHeight, 1);
>        if (!temp_dst) {
> -	 temp_dst = malloc(temp_dst_stride * dstHeight);
> +	 temp_dst = malloc(temp_dst_img_stride * dstDepth);
>  	 if (!temp_dst) {
>  	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
>  	    break;
> @@ -2117,13 +2131,23 @@ generate_mipmap_compressed(struct gl_context *ctx,
> GLenum target,
>           return;
>        }
>  
> -      /* rescale src image to dest image */
> +      /* for 2D arrays, setup array[depth] of slice pointers */
> +      for (i = 0; i < srcDepth; i++) {
> +         temp_src_slices[i] = temp_src + temp_src_img_stride * i;
> +      }
> +      for (i = 0; i < dstDepth; i++) {
> +         temp_dst_slices[i] = temp_dst + temp_dst_img_stride * i;
> +      }
> +
> +      /* Rescale src image to dest image.
> +       * This will loop over the slices of a 2D array.
> +       */
>        _mesa_generate_mipmap_level(target, temp_datatype, components, border,
>                                    srcWidth, srcHeight, srcDepth,
> -                                  (const GLubyte **) &temp_src,
> -                                  temp_src_stride,
> +                                  (const GLubyte **) temp_src_slices,
> +                                  temp_src_row_stride,
>                                    dstWidth, dstHeight, dstDepth,
> -                                  &temp_dst, temp_dst_stride);
> +                                  temp_dst_slices, temp_dst_row_stride);
>  
>        if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
>                                        dstWidth, dstHeight, dstDepth,
> @@ -2135,7 +2159,7 @@ generate_mipmap_compressed(struct gl_context *ctx,
> GLenum target,
>  
>        /* The image space was allocated above so use glTexSubImage now */
>        ctx->Driver.TexSubImage(ctx, 2, dstImage,
> -                              0, 0, 0, dstWidth, dstHeight, 1,
> +                              0, 0, 0, dstWidth, dstHeight, dstDepth,
>                                temp_base_format, temp_datatype,
>                                temp_dst, &ctx->DefaultPacking);
>  
> @@ -2144,12 +2168,15 @@ generate_mipmap_compressed(struct gl_context *ctx,
> GLenum target,
>  	 GLubyte *temp = temp_src;
>  	 temp_src = temp_dst;
>  	 temp_dst = temp;
> -	 temp_src_stride = temp_dst_stride;
> +         temp_src_row_stride = temp_dst_row_stride;
> +         temp_src_img_stride = temp_dst_img_stride;
>        }
>     } /* loop over mipmap levels */
>  
>     free(temp_src);
>     free(temp_dst);
> +   free(temp_src_slices);
> +   free(temp_dst_slices);
>  }
>  
>  /**
> --
> 1.7.10.4
> 
> _______________________________________________
> 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