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.
This commit is contained in:
Eric Anholt
2008-08-20 22:55:47 -07:00
parent 8f1d5ca086
commit 495c02262e
3 changed files with 65 additions and 38 deletions
+7 -2
View File
@@ -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
+8
View File
@@ -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);
+50 -36
View File
@@ -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_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;
for (face = 0; face < nr_faces; face++) {
struct intel_texture_image *intelImage =
intel_texture_image(intelObj->base.Image[face][level]);
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)
{
GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
GLuint face, i;
int i;
DBG("%s\n", __FUNCTION__);
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) {
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; */
}
}
}
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);
}