On 16/10/17 02:21 PM, Thomas Hellstrom wrote:
> 
> On 10/16/2017 12:53 PM, Thomas Hellstrom wrote:
>> Hi, Michel,
>>
>> On 10/16/2017 12:35 PM, Michel Dänzer wrote:
>>> Hi Thomas,
>>>
>>> On 05/09/17 10:15 AM, Thomas Hellstrom wrote:
>>>> If we're seeing a drawable size change, in particular after
>>>> processing a
>>>> configure notify event, make sure we invalidate so that the state
>>>> tracker
>>>> picks up the new geometry.
>>>>
>>>> Signed-off-by: Thomas Hellstrom <thellst...@vmware.com>
>>>> ---
>>>>   src/loader/loader_dri3_helper.c | 2 ++
>>>>   1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/src/loader/loader_dri3_helper.c
>>>> b/src/loader/loader_dri3_helper.c
>>>> index 51e4e97..bcd5a66 100644
>>>> --- a/src/loader/loader_dri3_helper.c
>>>> +++ b/src/loader/loader_dri3_helper.c
>>>> @@ -348,6 +348,7 @@ dri3_handle_present_event(struct
>>>> loader_dri3_drawable *draw,
>>>>         draw->width = ce->width;
>>>>         draw->height = ce->height;
>>>>         draw->vtable->set_drawable_size(draw, draw->width,
>>>> draw->height);
>>>> + draw->ext->flush->invalidate(draw->dri_drawable);
>>>>         break;
>>>>      }
>>>>      case XCB_PRESENT_COMPLETE_NOTIFY: {
>>>> @@ -1592,6 +1593,7 @@ loader_dri3_update_drawable_geometry(struct
>>>> loader_dri3_drawable *draw)
>>>>         draw->width = geom_reply->width;
>>>>         draw->height = geom_reply->height;
>>>>         draw->vtable->set_drawable_size(draw, draw->width,
>>>> draw->height);
>>>> + draw->ext->flush->invalidate(draw->dri_drawable);
>>>>           free(geom_reply);
>>>>      }
>>>>
>>> unfortunately, I just bisected a regression to this commit. With it, the
>>> pipe_resource textures backing DRI3 back buffers are leaked when the
>>> window is resized:
>>>
>>> ==3408== 273,760 (228,464 direct, 45,296 indirect) bytes in 131
>>> blocks are definitely lost in loss record 1,285 of 1,286
>>> ==3408==    at 0x4C2DC05: calloc (vg_replace_malloc.c:711)
>>> ==3408==    by 0xA04D5D3: r600_texture_create_object
>>> (r600_texture.c:1125)
>>> ==3408==    by 0xA04E1C1: si_texture_create (r600_texture.c:1382)
>>> ==3408==    by 0x9CE3A17: dri2_allocate_textures (dri2.c:803)
>>> ==3408==    by 0x9CDDAE2: dri_st_framebuffer_validate
>>> (dri_drawable.c:85)
>>> ==3408==    by 0x9B6D07F: st_framebuffer_validate (st_manager.c:195)
>>> ==3408==    by 0x9B6EE84: st_manager_validate_framebuffers
>>> (st_manager.c:1063)
>>> ==3408==    by 0x9B21807: st_validate_state (st_atom.c:202)
>>> ==3408==    by 0x9B2AF75: st_Clear (st_cb_clear.c:411)
>>> ==3408==    by 0x10A6BD: ??? (in /usr/bin/glxgears)
>>> ==3408==    by 0x109E37: ??? (in /usr/bin/glxgears)
>>> ==3408==    by 0x5E202E0: (below main) (libc-start.c:291)
>>> ==3408==
>>> ==3408== 362,768 (230,208 direct, 132,560 indirect) bytes in 132
>>> blocks are definitely lost in loss record 1,286 of 1,286
>>> ==3408==    at 0x4C2DC05: calloc (vg_replace_malloc.c:711)
>>> ==3408==    by 0xA04D5D3: r600_texture_create_object
>>> (r600_texture.c:1125)
>>> ==3408==    by 0xA04E1C1: si_texture_create (r600_texture.c:1382)
>>> ==3408==    by 0x9CE0C0D: dri2_create_image_common (dri2.c:1119)
>>> ==3408==    by 0x9CE0C6F: dri2_create_image (dri2.c:1140)
>>> ==3408==    by 0x5386BA8: dri3_alloc_render_buffer
>>> (loader_dri3_helper.c:1030)
>>> ==3408==    by 0x53876F4: dri3_get_buffer.isra.15
>>> (loader_dri3_helper.c:1364)
>>> ==3408==    by 0x53886DC: loader_dri3_get_buffers
>>> (loader_dri3_helper.c:1549)
>>> ==3408==    by 0x9CE298C: dri_image_drawable_get_buffers (dri2.c:452)
>>> ==3408==    by 0x9CE298C: dri2_allocate_textures (dri2.c:576)
>>> ==3408==    by 0x9CDDAE2: dri_st_framebuffer_validate
>>> (dri_drawable.c:85)
>>> ==3408==    by 0x9B6D07F: st_framebuffer_validate (st_manager.c:195)
>>> ==3408==    by 0x9B6EE84: st_manager_validate_framebuffers
>>> (st_manager.c:1063)
>>>
>>>
>>> Can you reproduce this with vmwgfx as well? Any ideas why this is
>>> happening / how to fix it?
>>>
>>>
>> Looks like other buffers (depth ?) are leaked too, outside dri3, right?
>>
>> I'll take a look.
>>
>> /Thomas
>>
>>
> Could you try the attached patch? Fixes the issue on my side.

Yes, it fixes the problem for me as well, thanks! I was looking at that
code as well, but didn't realize what's going on.

I think the attached patch would be a cleaner solution though.

Some comments on your patch, assuming we end up going with that:


> +      /* If we need to rerun the validation, make sure we unreference the
> +       * textures first. The validate function will just clear the pointers.
> +       */
> +
> +      if (stfb->iface_stamp != new_stamp) {
> +         for (i = 0; i < stfb->num_statts; ++i) {
> +            pipe_resource_reference(&textures[i], NULL);
> +         }
> +      }

I'd drop the blank line after the comment and the curly braces around
the inner loop, but either way, with

Fixes: e96d175c7d2e "loader/dri3: Make sure we invalidate a drawable on
                     size change"

added to the commit log,

Reviewed-and-Tested-by: Michel Dänzer <michel.daen...@amd.com>


-- 
Earthling Michel Dänzer               |               http://www.amd.com
Libre software enthusiast             |             Mesa and X developer
From 9eec660e3374ea43d82be9a60769dc001971b034 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daen...@amd.com>
Date: Mon, 16 Oct 2017 16:35:18 +0200
Subject: [PATCH] st/mesa: Initialize textures array in st_framebuffer_validate
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

And just reference pipe_resources to it in the validate callbacks.

Avoids pipe_resource leaks when st_framebuffer_validate ends up calling
the validate callback multiple times.

Fixes: e96d175c7d2e "loader/dri3: Make sure we invalidate a drawable on
                     size change"
Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
---
 src/gallium/state_trackers/dri/dri_drawable.c |  4 +---
 src/gallium/state_trackers/glx/xlib/xm_st.c   |  4 +---
 src/gallium/state_trackers/hgl/hgl.c          |  4 +---
 src/gallium/state_trackers/osmesa/osmesa.c    |  1 +
 src/gallium/state_trackers/wgl/stw_st.c       |  4 +---
 src/mesa/state_tracker/st_manager.c           | 12 ++++++++++--
 6 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 75a8197d330..d586b7564ef 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -99,10 +99,8 @@ dri_st_framebuffer_validate(struct st_context_iface *stctx,
       return TRUE;
 
    /* Set the window-system buffers for the state tracker. */
-   for (i = 0; i < count; i++) {
-      out[i] = NULL;
+   for (i = 0; i < count; i++)
       pipe_resource_reference(&out[i], textures[statts[i]]);
-   }
 
    return TRUE;
 }
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
index 0c42e653c76..946b5dcff29 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_st.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -245,10 +245,8 @@ xmesa_st_framebuffer_validate(struct st_context_iface *stctx,
       }
    }
 
-   for (i = 0; i < count; i++) {
-      out[i] = NULL;
+   for (i = 0; i < count; i++)
       pipe_resource_reference(&out[i], xstfb->textures[statts[i]]);
-   }
 
    return TRUE;
 }
diff --git a/src/gallium/state_trackers/hgl/hgl.c b/src/gallium/state_trackers/hgl/hgl.c
index 1b702815a3a..bbc477a978c 100644
--- a/src/gallium/state_trackers/hgl/hgl.c
+++ b/src/gallium/state_trackers/hgl/hgl.c
@@ -193,10 +193,8 @@ hgl_st_framebuffer_validate(struct st_context_iface *stctxi,
 		//}
 	}
 
-	for (i = 0; i < count; i++) {
-		out[i] = NULL;
+	for (i = 0; i < count; i++)
 		pipe_resource_reference(&out[i], buffer->textures[statts[i]]);
-	}
 
 	return TRUE;
 }
diff --git a/src/gallium/state_trackers/osmesa/osmesa.c b/src/gallium/state_trackers/osmesa/osmesa.c
index 2f9558db312..44a0cc43812 100644
--- a/src/gallium/state_trackers/osmesa/osmesa.c
+++ b/src/gallium/state_trackers/osmesa/osmesa.c
@@ -432,6 +432,7 @@ osmesa_st_framebuffer_validate(struct st_context_iface *stctx,
 
       templat.format = format;
       templat.bind = bind;
+      pipe_resource_reference(&out[i], NULL);
       out[i] = osbuffer->textures[statts[i]] =
          screen->resource_create(screen, &templat);
    }
diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c
index 5e165c89f56..7cf18f0a8b0 100644
--- a/src/gallium/state_trackers/wgl/stw_st.c
+++ b/src/gallium/state_trackers/wgl/stw_st.c
@@ -161,10 +161,8 @@ stw_st_framebuffer_validate(struct st_context_iface *stctx,
       stwfb->fb->must_resize = FALSE;
    }
 
-   for (i = 0; i < count; i++) {
-      out[i] = NULL;
+   for (i = 0; i < count; i++)
       pipe_resource_reference(&out[i], stwfb->textures[statts[i]]);
-   }
 
    stw_framebuffer_unlock(stwfb->fb);
 
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 50bc3c33c62..76b7b46ff51 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -53,6 +53,7 @@
 
 #include "pipe/p_context.h"
 #include "pipe/p_screen.h"
+#include "os/os_memory.h"
 #include "util/u_format.h"
 #include "util/u_pointer.h"
 #include "util/u_inlines.h"
@@ -180,7 +181,7 @@ static void
 st_framebuffer_validate(struct st_framebuffer *stfb,
                         struct st_context *st)
 {
-   struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
+   struct pipe_resource **textures;
    uint width, height;
    unsigned i;
    boolean changed = FALSE;
@@ -190,11 +191,15 @@ st_framebuffer_validate(struct st_framebuffer *stfb,
    if (stfb->iface_stamp == new_stamp)
       return;
 
+   textures = os_calloc(stfb->num_statts, sizeof(textures[0]));
+   if (!textures)
+      return;
+
    /* validate the fb */
    do {
       if (!stfb->iface->validate(&st->iface, stfb->iface, stfb->statts,
                                  stfb->num_statts, textures))
-         return;
+         goto cleanup;
 
       stfb->iface_stamp = new_stamp;
       new_stamp = p_atomic_read(&stfb->iface->stamp);
@@ -253,6 +258,9 @@ st_framebuffer_validate(struct st_framebuffer *stfb,
       ++stfb->stamp;
       _mesa_resize_framebuffer(st->ctx, &stfb->Base, width, height);
    }
+
+cleanup:
+   free(textures);
 }
 
 /**
-- 
2.15.0.rc0

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to