From 495c02262eaaa68f2df23c2265362da51851c57a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 20 Aug 2008 22:55:47 -0700 Subject: intel: Fix SGIS_generate_mipmap after a miptree had been validated. Previously, the updated images would be ignored because the miptree in the image matched the miptree in the object, even though Mesa core had just attached updated contents in ->Data. Additionally, Mesa core could have tried to free inside our miptree if it had already been validated. Fixes bug #17077. --- src/mesa/drivers/dri/intel/intel_tex.c | 9 ++- src/mesa/drivers/dri/intel/intel_tex.h | 8 +++ src/mesa/drivers/dri/intel/intel_tex_validate.c | 80 +++++++++++++++---------- 3 files changed, 62 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c index f1d6a6dbfc..4fa18e2d54 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.c +++ b/src/mesa/drivers/dri/intel/intel_tex.c @@ -174,6 +174,7 @@ void intel_generate_mipmap(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj) { + struct intel_context *intel = intel_context(ctx); struct intel_texture_object *intelObj = intel_texture_object(texObj); GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; int face, i; @@ -193,6 +194,10 @@ intel_generate_mipmap(GLcontext *ctx, GLenum target, intelImage->level = i; intelImage->face = face; + /* Unreference the miptree to signal that the new Data is a bare + * pointer from mesa. + */ + intel_miptree_release(intel, &intelImage->mt); } } } @@ -202,9 +207,9 @@ static void intelGenerateMipmap(GLcontext *ctx, GLenum target, struct gl_texture struct intel_context *intel = intel_context(ctx); struct intel_texture_object *intelObj = intel_texture_object(texObj); - intel_tex_map_images(intel, intelObj); + intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel); intel_generate_mipmap(ctx, target, texObj); - intel_tex_unmap_images(intel, intelObj); + intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel); } void diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index 60ab8203e5..fe7a8badf8 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -142,6 +142,14 @@ void intelSetTexBuffer(__DRIcontext *pDRICtx, GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); +void intel_tex_map_level_images(struct intel_context *intel, + struct intel_texture_object *intelObj, + int level); + +void intel_tex_unmap_level_images(struct intel_context *intel, + struct intel_texture_object *intelObj, + int level); + void intel_tex_map_images(struct intel_context *intel, struct intel_texture_object *intelObj); diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index 9fe4aac149..5763f4ae1f 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -231,56 +231,70 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) return GL_TRUE; } +void +intel_tex_map_level_images(struct intel_context *intel, + struct intel_texture_object *intelObj, + int level) +{ + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + GLuint face; + for (face = 0; face < nr_faces; face++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][level]); + + if (intelImage->mt) { + intelImage->base.Data = + intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &intelImage->base.RowStride, + intelImage->base.ImageOffsets); + /* convert stride to texels, not bytes */ + intelImage->base.RowStride /= intelImage->mt->cpp; + /* intelImage->base.ImageStride /= intelImage->mt->cpp; */ + } + } +} void -intel_tex_map_images(struct intel_context *intel, - struct intel_texture_object *intelObj) +intel_tex_unmap_level_images(struct intel_context *intel, + struct intel_texture_object *intelObj, + int level) { GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - GLuint face, i; - - DBG("%s\n", __FUNCTION__); + GLuint face; for (face = 0; face < nr_faces; face++) { - for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { - struct intel_texture_image *intelImage = - intel_texture_image(intelObj->base.Image[face][i]); + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][level]); - if (intelImage->mt) { - intelImage->base.Data = - intel_miptree_image_map(intel, - intelImage->mt, - intelImage->face, - intelImage->level, - &intelImage->base.RowStride, - intelImage->base.ImageOffsets); - /* convert stride to texels, not bytes */ - intelImage->base.RowStride /= intelImage->mt->cpp; -/* intelImage->base.ImageStride /= intelImage->mt->cpp; */ - } + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + intelImage->base.Data = NULL; } } } +void +intel_tex_map_images(struct intel_context *intel, + struct intel_texture_object *intelObj) +{ + int i; + + DBG("%s\n", __FUNCTION__); + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) + intel_tex_map_level_images(intel, intelObj, i); +} void intel_tex_unmap_images(struct intel_context *intel, struct intel_texture_object *intelObj) { - GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - GLuint face, i; + int i; - for (face = 0; face < nr_faces; face++) { - for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { - struct intel_texture_image *intelImage = - intel_texture_image(intelObj->base.Image[face][i]); - - if (intelImage->mt) { - intel_miptree_image_unmap(intel, intelImage->mt); - intelImage->base.Data = NULL; - } - } - } + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) + intel_tex_unmap_level_images(intel, intelObj, i); } -- cgit v1.2.3