Mesa (master): st/mesa: fix mipmap generation for immutable textures with incomplete pyramids

Nicolai Hähnle nh at kemper.freedesktop.org
Thu Oct 29 22:59:11 UTC 2015


Module: Mesa
Branch: master
Commit: 24c90888aeaf90b13700389b91b74bf63ee9f28d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=24c90888aeaf90b13700389b91b74bf63ee9f28d

Author: Nicolai Hähnle <nhaehnle at gmail.com>
Date:   Fri Oct 23 01:06:15 2015 +0200

st/mesa: fix mipmap generation for immutable textures with incomplete pyramids

Without the clamping by NumLevels, the state tracker would reallocate the
texture storage (incorrect) and even fail to copy the base level image
after reallocation, leading to the graphical glitch of
https://bugs.freedesktop.org/show_bug.cgi?id=91993 .

A piglit test has been submitted for review as well (subtest of
arb_texture_storage-texture-storage).

v2: also bypass all calls to st_finalize_texture (suggested by Marek Olšák)

Cc: mesa-stable at lists.freedesktop.org
Reviewed-by: Marek Olšák <marek.olsak at amd.com>

---

 src/mesa/state_tracker/st_gen_mipmap.c |   68 +++++++++++++++++---------------
 1 file changed, 36 insertions(+), 32 deletions(-)

diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 26e1c21..b370040 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -61,6 +61,8 @@ compute_num_levels(struct gl_context *ctx,
 
    numLevels = texObj->BaseLevel + baseImage->MaxNumLevels;
    numLevels = MIN2(numLevels, (GLuint) texObj->MaxLevel + 1);
+   if (texObj->Immutable)
+      numLevels = MIN2(numLevels, texObj->NumLevels);
    assert(numLevels >= 1);
 
    return numLevels;
@@ -99,38 +101,40 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
     */
    stObj->lastLevel = lastLevel;
 
-   if (pt->last_level < lastLevel) {
-      /* The current gallium texture doesn't have space for all the
-       * mipmap levels we need to generate.  So allocate a new texture.
-       */
-      struct pipe_resource *oldTex = stObj->pt;
-
-      /* create new texture with space for more levels */
-      stObj->pt = st_texture_create(st,
-                                    oldTex->target,
-                                    oldTex->format,
-                                    lastLevel,
-                                    oldTex->width0,
-                                    oldTex->height0,
-                                    oldTex->depth0,
-                                    oldTex->array_size,
-                                    0,
-                                    oldTex->bind);
-
-      /* This will copy the old texture's base image into the new texture
-       * which we just allocated.
-       */
-      st_finalize_texture(ctx, st->pipe, texObj);
-
-      /* release the old tex (will likely be freed too) */
-      pipe_resource_reference(&oldTex, NULL);
-      st_texture_release_all_sampler_views(st, stObj);
-   }
-   else {
-      /* Make sure that the base texture image data is present in the
-       * texture buffer.
-       */
-      st_finalize_texture(ctx, st->pipe, texObj);
+   if (!texObj->Immutable) {
+      if (pt->last_level < lastLevel) {
+         /* The current gallium texture doesn't have space for all the
+         * mipmap levels we need to generate.  So allocate a new texture.
+         */
+         struct pipe_resource *oldTex = stObj->pt;
+
+         /* create new texture with space for more levels */
+         stObj->pt = st_texture_create(st,
+                                       oldTex->target,
+                                       oldTex->format,
+                                       lastLevel,
+                                       oldTex->width0,
+                                       oldTex->height0,
+                                       oldTex->depth0,
+                                       oldTex->array_size,
+                                       0,
+                                       oldTex->bind);
+
+         /* This will copy the old texture's base image into the new texture
+         * which we just allocated.
+         */
+         st_finalize_texture(ctx, st->pipe, texObj);
+
+         /* release the old tex (will likely be freed too) */
+         pipe_resource_reference(&oldTex, NULL);
+         st_texture_release_all_sampler_views(st, stObj);
+      }
+      else {
+         /* Make sure that the base texture image data is present in the
+         * texture buffer.
+         */
+         st_finalize_texture(ctx, st->pipe, texObj);
+      }
    }
 
    pt = stObj->pt;




More information about the mesa-commit mailing list