[Mesa-dev] [PATCH] [RFC] st/mesa: overhaul texture maxlevel handling and fallout

Dave Airlie airlied at gmail.com
Wed Apr 9 23:12:06 PDT 2014


So I wanted to implement ARB_texture_query_levels, in order to get the
right answers I had to make sure the gallium texture has the same levels
as the mesa one, so the hw is programmed correctly.

This led to some fallout as we were suddenly hitting the finalize texture
reallocation path in cases we hadn't before.

a) array texture - simple patch to deal with array textures,

b) getteximage-formats fail due to memory not being allocated, removing
the sampler filter checks fixed thism,

c) getteximage-formats further fail due to replacing levels of a texture
with ones with different formats, so check the formats before we bother
copying over levels, fixes segfaults

d) glean fbo test started failing, because the stObj pt was being reallocated
however a surface was already pointing at the old stObj->pt, I added a check
to see if the renderbuffer texture resource is the same as the strb one,
and if not it regenerates stuff.

It's a bit of a mess in there, and some of these things might have been optimisations but I think we need to do better if they are.

Dave.
---
 src/mesa/state_tracker/st_cb_fbo.c     | 11 +++++++++++
 src/mesa/state_tracker/st_cb_texture.c | 10 +++-------
 src/mesa/state_tracker/st_texture.c    |  6 ++++++
 src/mesa/state_tracker/st_texture.h    |  7 +++++++
 4 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index ce8d915..dca47e2 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -408,6 +408,7 @@ st_update_renderbuffer_surface(struct st_context *st,
 {
    struct pipe_context *pipe = st->pipe;
    struct pipe_resource *resource = strb->texture;
+   struct pipe_resource *pt;
    int rtt_width = strb->Base.Width;
    int rtt_height = strb->Base.Height;
    int rtt_depth = strb->Base.Depth;
@@ -424,6 +425,16 @@ st_update_renderbuffer_surface(struct st_context *st,
       util_format_linear(resource->format);
    unsigned first_layer, last_layer, level;
 
+   if (strb->is_rtt == 1) {
+      /* the texture could have been replaced by a finalize texture pass */
+      pt = st_get_teximage_resource(strb->Base.TexImage);
+      if (pt != strb->texture) {
+         pipe_resource_reference(&strb->texture, pt);
+         pipe_surface_reference(&strb->surface, NULL);
+         resource = pt;
+      }
+   }
+
    if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
       rtt_depth = rtt_height;
       rtt_height = 1;
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 353415b..9d81990 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -1473,11 +1473,7 @@ st_finalize_texture(struct gl_context *ctx,
        * incomplete.  In that case, we'll have set stObj->lastLevel before
        * we get here.
        */
-      if (stObj->base.Sampler.MinFilter == GL_LINEAR ||
-          stObj->base.Sampler.MinFilter == GL_NEAREST)
-         stObj->lastLevel = stObj->base.BaseLevel;
-      else
-         stObj->lastLevel = stObj->base._MaxLevel;
+      stObj->lastLevel = stObj->base._MaxLevel;
    }
 
    if (tObj->Target == GL_TEXTURE_BUFFER) {
@@ -1548,7 +1544,7 @@ st_finalize_texture(struct gl_context *ctx,
    if (stObj->pt) {
       if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
           stObj->pt->format != firstImageFormat ||
-          stObj->pt->last_level < stObj->lastLevel ||
+          stObj->pt->last_level != stObj->lastLevel ||
           stObj->pt->width0 != ptWidth ||
           stObj->pt->height0 != ptHeight ||
           stObj->pt->depth0 != ptDepth ||
@@ -1595,7 +1591,7 @@ st_finalize_texture(struct gl_context *ctx,
 
          /* Need to import images in main memory or held in other textures.
           */
-         if (stImage && stObj->pt != stImage->pt) {
+         if (stImage && stObj->pt != stImage->pt && stObj->pt->format == stImage->pt->format) {
             if (level == 0 ||
                 (stImage->base.Width == u_minify(stObj->width0, level) &&
                  stImage->base.Height == u_minify(stObj->height0, level) &&
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 8d559df..3a27eeb 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -373,6 +373,12 @@ st_texture_image_copy(struct pipe_context *pipe,
    src_box.width = width;
    src_box.height = height;
    src_box.depth = 1;
+
+   if (src->target == PIPE_TEXTURE_1D_ARRAY ||
+       src->target == PIPE_TEXTURE_2D_ARRAY) {
+      face = 0;
+      depth = src->array_size;
+   }
    /* Loop over 3D image slices */
    /* could (and probably should) use "true" 3d box here -
       but drivers can't quite handle it yet */
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index 87de9f9..bcd3db4 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -129,6 +129,13 @@ st_get_texobj_resource(struct gl_texture_object *texObj)
    return stObj ? stObj->pt : NULL;
 }
 
+static INLINE struct pipe_resource *
+st_get_teximage_resource(struct gl_texture_image *texImage)
+{
+   struct st_texture_image *stImage = st_texture_image(texImage);
+   return stImage ? stImage->pt : NULL;
+}
+
 
 static INLINE struct pipe_resource *
 st_get_stobj_resource(struct st_texture_object *stObj)
-- 
1.9.0



More information about the mesa-dev mailing list