From 101abee6c4fc2c9284ff2ba6f9f9138327d6963d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 19 Dec 2007 14:26:14 -0800 Subject: [intel] Fix and reenable (software) SGIS_generate_mipmap The core problem was that _mesa_generate_mipmap was not respecting RowStride of the source image. Additionally, the intel private data associated with the images (level and face) was not being initialized for the _mesa_generate_mipmap-generated images. --- src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 2 +- src/mesa/drivers/dri/intel/intel_tex.c | 41 +++++++++++++++++++++++++ src/mesa/drivers/dri/intel/intel_tex.h | 4 +++ src/mesa/drivers/dri/intel/intel_tex_copy.c | 19 ++++++------ src/mesa/drivers/dri/intel/intel_tex_image.c | 22 ++++++------- src/mesa/drivers/dri/intel/intel_tex_subimage.c | 4 +-- src/mesa/drivers/dri/intel/intel_tex_validate.c | 4 +++ 7 files changed, 70 insertions(+), 26 deletions(-) (limited to 'src/mesa/drivers/dri/intel') diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 6610771b6e..7637585033 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -351,7 +351,7 @@ intel_miptree_image_data(struct intel_context *intel, GLuint i; GLuint height = 0; - DBG("%s\n", __FUNCTION__); + DBG("%s: %d/%d\n", __FUNCTION__, face, level); for (i = 0; i < depth; i++) { height = dst->level[level].height; if(dst->compressed) diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c index e02972ec63..f016b6b4dc 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.c +++ b/src/mesa/drivers/dri/intel/intel_tex.c @@ -1,5 +1,6 @@ #include "swrast/swrast.h" #include "texobj.h" +#include "mipmap.h" #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" @@ -156,6 +157,46 @@ timed_memcpy(void *dest, const void *src, size_t n) } #endif /* DO_DEBUG */ +/** + * Generate new mipmap data from BASE+1 to BASE+p (the minimally-sized mipmap + * level). + * + * The texture object's miptree must be mapped. + * + * It would be really nice if this was just called by Mesa whenever mipmaps + * needed to be regenerated, rather than us having to remember to do so in + * each texture image modification path. + * + * This function should also include an accelerated path. + */ +void +intel_generate_mipmap(GLcontext *ctx, GLenum target, + const struct gl_texture_unit *texUnit, + struct gl_texture_object *texObj) +{ + struct intel_texture_object *intelObj = intel_texture_object(texObj); + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + int face, i; + + _mesa_generate_mipmap(ctx, target, texUnit, texObj); + + /* Update the level information in our private data in the new images, since + * it didn't get set as part of a normal TexImage path. + */ + for (face = 0; face < nr_faces; face++) { + for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { + struct intel_texture_image *intelImage; + + intelImage = intel_texture_image(texObj->Image[face][i]); + if (intelImage == NULL) + break; + + intelImage->level = i; + intelImage->face = face; + } + } +} + void intelInitTextureFuncs(struct dd_function_table *functions) diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index b77d7a1d8a..2973e0ceb9 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -148,4 +148,8 @@ void intel_tex_unmap_images(struct intel_context *intel, int intel_compressed_num_bytes(GLuint mesaFormat); +void intel_generate_mipmap(GLcontext *ctx, GLenum target, + const struct gl_texture_unit *texUnit, + struct gl_texture_object *texObj); + #endif diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index f1a455a04c..521ce06640 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -29,6 +29,7 @@ #include "enums.h" #include "image.h" #include "teximage.h" +#include "mipmap.h" #include "swrast/swrast.h" #include "intel_screen.h" @@ -85,12 +86,14 @@ get_teximage_source(struct intel_context *intel, GLenum internalFormat) static GLboolean do_copy_texsubimage(struct intel_context *intel, + GLenum target, struct intel_texture_image *intelImage, GLenum internalFormat, GLint dstx, GLint dsty, GLint x, GLint y, GLsizei width, GLsizei height) { GLcontext *ctx = &intel->ctx; + struct gl_texture_object *texObj = intelImage->base.TexObject; const struct intel_region *src = get_teximage_source(intel, internalFormat); @@ -156,16 +159,12 @@ do_copy_texsubimage(struct intel_context *intel, UNLOCK_HARDWARE(intel); -#if 0 - /* GL_SGIS_generate_mipmap -- this can be accelerated now. - * XXX Add a ctx->Driver.GenerateMipmaps() function? - */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + /* GL_SGIS_generate_mipmap */ + if (intelImage->level == texObj->BaseLevel && texObj->GenerateMipmap) { intel_generate_mipmap(ctx, target, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } -#endif return GL_TRUE; } @@ -197,7 +196,7 @@ intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, GL_RGBA, CHAN_TYPE, NULL, &ctx->DefaultPacking, texObj, texImage); - if (!do_copy_texsubimage(intel_context(ctx), + if (!do_copy_texsubimage(intel_context(ctx), target, intel_texture_image(texImage), internalFormat, 0, 0, x, y, width, 1)) goto fail; @@ -234,7 +233,7 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, &ctx->DefaultPacking, texObj, texImage); - if (!do_copy_texsubimage(intel_context(ctx), + if (!do_copy_texsubimage(intel_context(ctx), target, intel_texture_image(texImage), internalFormat, 0, 0, x, y, width, height)) goto fail; @@ -264,7 +263,7 @@ intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, /* Need to check texture is compatible with source format. */ - if (!do_copy_texsubimage(intel_context(ctx), + if (!do_copy_texsubimage(intel_context(ctx), target, intel_texture_image(texImage), internalFormat, xoffset, 0, x, y, width, 1)) { _swrast_copy_texsubimage1d(ctx, target, level, xoffset, x, y, width); @@ -290,7 +289,7 @@ intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, /* Need to check texture is compatible with source format. */ - if (!do_copy_texsubimage(intel_context(ctx), + if (!do_copy_texsubimage(intel_context(ctx), target, intel_texture_image(texImage), internalFormat, xoffset, yoffset, x, y, width, height)) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index c2af74095c..4f5f75d049 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -466,6 +466,7 @@ intelTexImage(GLcontext * ctx, intelImage->level, &dstRowStride, intelImage->base.ImageOffsets); + texImage->RowStride = dstRowStride / intelImage->mt->cpp; } else { /* Allocate regular memory and store the image there temporarily. */ @@ -483,8 +484,8 @@ intelTexImage(GLcontext * ctx, texImage->Data = malloc(sizeInBytes); } - DBG("Upload image %dx%dx%d row_len %x " - "pitch %x\n", + DBG("Upload image %dx%dx%d row_len %d " + "pitch %d\n", width, height, depth, width * texelBytes, dstRowStride); /* Copy data. Would like to know when it's ok for us to eg. use @@ -504,6 +505,13 @@ intelTexImage(GLcontext * ctx, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); } + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } + _mesa_unmap_teximage_pbo(ctx, unpack); if (intelImage->mt) { @@ -512,16 +520,6 @@ intelTexImage(GLcontext * ctx, } UNLOCK_HARDWARE(intel); - -#if 0 - /* GL_SGIS_generate_mipmap -- this can be accelerated now. - */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); - } -#endif } void diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c index 5410df203f..bd27b86bf3 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c @@ -90,14 +90,12 @@ intelTexSubimage(GLcontext * ctx, _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); } -#if 0 /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - _mesa_generate_mipmap(ctx, target, + intel_generate_mipmap(ctx, target, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], texObj); } -#endif _mesa_unmap_teximage_pbo(ctx, packing); diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index 8df66ad445..d260a721d9 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -75,6 +75,10 @@ intel_calculate_first_last_level(struct intel_texture_object *intelObj) intelObj->lastLevel = lastLevel; } +/** + * Copies the image's contents at its level into the object's miptree, + * and updates the image to point at the object's miptree. + */ static void copy_image_data_to_tree(struct intel_context *intel, struct intel_texture_object *intelObj, -- cgit v1.2.3