intel: Fix SGIS_generate_mipmap after a miptree had been validated.
authorEric Anholt <eric@anholt.net>
Thu, 21 Aug 2008 05:55:47 +0000 (22:55 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 21 Aug 2008 06:18:02 +0000 (23:18 -0700)
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
src/mesa/drivers/dri/intel/intel_tex.h
src/mesa/drivers/dri/intel/intel_tex_validate.c

index f1d6a6d..4fa18e2 100644 (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
index 60ab820..fe7a8ba 100644 (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);
 
index 9fe4aac..5763f4a 100644 (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_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);
 }