[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