Re: [Mesa-dev] [PATCH 1/8] st/mesa: implement "zombie" sampler views

2019-03-15 Thread Stéphane Marchesin
On Fri, Mar 15, 2019 at 8:55 AM Jose Fonseca  wrote:
>
> On 14/03/2019 19:37, Brian Paul wrote:
> > When st_texture_release_all_sampler_views() is called the texture may
> > have sampler views belonging to several contexts.  If we unreference a
> > sampler view and its refcount hits zero, we need to be sure to destroy
> > the sampler view with the same context which created it.
> >
> > This was not the case with the previous code which used
> > pipe_sampler_view_release().  That function could end up freeing a
> > sampler view with a context different than the one which created it.
> > In the case of the VMware svga driver, we detected this but leaked the
> > sampler view.  This led to a crash with google-chrome when the kernel
> > module had too many sampler views.  VMware bug 2274734.
> >
> > Alternately, if we try to delete a sampler view with the correct
> > context, we may be "reaching into" a context which is active on
> > another thread.  That's not safe.
> >
> > To fix these issues this patch adds a per-context list of "zombie"
> > sampler views.  These are views which are to be freed at some point
> > when the context is active.  Other contexts may safely add sampler
> > views to the zombie list at any time (it's mutex protected).  This
> > avoids the context/view ownership mix-ups we had before.
> >
> > Tested with: google-chrome, google earth, Redway3D Watch/Turbine demos
> > a few Linux games.  If anyone can recomment some other multi-threaded,
> > multi-context GL apps to test, please let me know.
> > ---
> >   src/mesa/state_tracker/st_cb_flush.c |  6 +++
> >   src/mesa/state_tracker/st_context.c  | 81 
> > 
> >   src/mesa/state_tracker/st_context.h  | 25 ++
> >   src/mesa/state_tracker/st_sampler_view.c | 27 +--
> >   src/mesa/state_tracker/st_texture.h  |  3 ++
> >   5 files changed, 138 insertions(+), 4 deletions(-)
> >
> > diff --git a/src/mesa/state_tracker/st_cb_flush.c 
> > b/src/mesa/state_tracker/st_cb_flush.c
> > index 5b3188c..81e5338 100644
> > --- a/src/mesa/state_tracker/st_cb_flush.c
> > +++ b/src/mesa/state_tracker/st_cb_flush.c
> > @@ -39,6 +39,7 @@
> >   #include "st_cb_flush.h"
> >   #include "st_cb_clear.h"
> >   #include "st_cb_fbo.h"
> > +#include "st_context.h"
> >   #include "st_manager.h"
> >   #include "pipe/p_context.h"
> >   #include "pipe/p_defines.h"
> > @@ -53,6 +54,11 @@ st_flush(struct st_context *st,
> >   {
> >  st_flush_bitmap_cache(st);
> >
> > +   /* We want to call this function periodically.
> > +* Typically, it has nothing to do so it shouldn't be expensive.
> > +*/
> > +   st_context_free_zombie_objects(st);
> > +
> >  st->pipe->flush(st->pipe, fence, flags);
> >   }
> >
> > diff --git a/src/mesa/state_tracker/st_context.c 
> > b/src/mesa/state_tracker/st_context.c
> > index 2898279..bd919da 100644
> > --- a/src/mesa/state_tracker/st_context.c
> > +++ b/src/mesa/state_tracker/st_context.c
> > @@ -261,6 +261,80 @@ st_invalidate_state(struct gl_context *ctx)
> >   }
> >
> >
> > +/*
> > + * In some circumstances (such as running google-chrome) the state
> > + * tracker may try to delete a resource view from a context different
> > + * than when it was created.  We don't want to do that.
> > + * In that situation, st_texture_release_all_sampler_views() calls this
> > + * function to save the view for later deletion.  The context here is
> > + * expected to be the context which created the view.
> > + */
> > +void
> > +st_save_zombie_sampler_view(struct st_context *st,
> > +struct pipe_sampler_view *view)
> > +{
> > +   struct st_zombie_sampler_view_node *entry;
> > +
> > +   assert(view->context == st->pipe);
> > +   assert(view->reference.count == 1);
> > +
> > +   entry = MALLOC_STRUCT(st_zombie_sampler_view_node);
> > +   if (!entry)
> > +  return;
> > +
> > +   entry->view = view;
> > +
> > +   /* We need a mutex since this function may be called from one thread
> > +* while free_zombie_resource_views() is called from another.
> > +*/
> > +   mtx_lock(&st->zombie_sampler_views.mutex);
> > +   LIST_ADDTAIL(&entry->node, &st->zombie_sampler_views.list.node);
> > +   mtx_unlock(&st->zombie_sampler_views.mutex);
> > +}
> > +
> > +
> > +/*
> > + * Free any zombie sampler views that may be attached to this context.
> > + */
> > +static void
> > +free_zombie_sampler_views(struct st_context *st)
> > +{
> > +   struct st_zombie_sampler_view_node *entry, *next;
> > +
> > +   if (LIST_IS_EMPTY(&st->zombie_sampler_views.list.node)) {
> > +  return;
> > +   }
> > +
> > +   mtx_lock(&st->zombie_sampler_views.mutex);
> > +
> > +   LIST_FOR_EACH_ENTRY_SAFE(entry, next,
> > +&st->zombie_sampler_views.list.node, node) {
> > +  LIST_DEL(&entry->node);  // remove this entry from the list
> > +
> > +  assert(entry->view->context == st->pipe);
> > +  assert(entry->view->reference.count == 1);
> > +  pipe_sam

Re: [Mesa-dev] [PATCH 1/8] st/mesa: implement "zombie" sampler views

2019-03-15 Thread Brian Paul

On 03/15/2019 09:54 AM, Jose Fonseca wrote:

On 14/03/2019 19:37, Brian Paul wrote:

When st_texture_release_all_sampler_views() is called the texture may
have sampler views belonging to several contexts.  If we unreference a
sampler view and its refcount hits zero, we need to be sure to destroy
the sampler view with the same context which created it.

This was not the case with the previous code which used
pipe_sampler_view_release().  That function could end up freeing a
sampler view with a context different than the one which created it.
In the case of the VMware svga driver, we detected this but leaked the
sampler view.  This led to a crash with google-chrome when the kernel
module had too many sampler views.  VMware bug 2274734.

Alternately, if we try to delete a sampler view with the correct
context, we may be "reaching into" a context which is active on
another thread.  That's not safe.

To fix these issues this patch adds a per-context list of "zombie"
sampler views.  These are views which are to be freed at some point
when the context is active.  Other contexts may safely add sampler
views to the zombie list at any time (it's mutex protected).  This
avoids the context/view ownership mix-ups we had before.

Tested with: google-chrome, google earth, Redway3D Watch/Turbine demos
a few Linux games.  If anyone can recomment some other multi-threaded,
multi-context GL apps to test, please let me know.
---
  src/mesa/state_tracker/st_cb_flush.c |  6 +++
  src/mesa/state_tracker/st_context.c  | 81 


  src/mesa/state_tracker/st_context.h  | 25 ++
  src/mesa/state_tracker/st_sampler_view.c | 27 +--
  src/mesa/state_tracker/st_texture.h  |  3 ++
  5 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_flush.c 
b/src/mesa/state_tracker/st_cb_flush.c

index 5b3188c..81e5338 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -39,6 +39,7 @@
  #include "st_cb_flush.h"
  #include "st_cb_clear.h"
  #include "st_cb_fbo.h"
+#include "st_context.h"
  #include "st_manager.h"
  #include "pipe/p_context.h"
  #include "pipe/p_defines.h"
@@ -53,6 +54,11 @@ st_flush(struct st_context *st,
  {
 st_flush_bitmap_cache(st);
+   /* We want to call this function periodically.
+    * Typically, it has nothing to do so it shouldn't be expensive.
+    */
+   st_context_free_zombie_objects(st);
+
 st->pipe->flush(st->pipe, fence, flags);
  }
diff --git a/src/mesa/state_tracker/st_context.c 
b/src/mesa/state_tracker/st_context.c

index 2898279..bd919da 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -261,6 +261,80 @@ st_invalidate_state(struct gl_context *ctx)
  }
+/*
+ * In some circumstances (such as running google-chrome) the state
+ * tracker may try to delete a resource view from a context different
+ * than when it was created.  We don't want to do that.
+ * In that situation, st_texture_release_all_sampler_views() calls this
+ * function to save the view for later deletion.  The context here is
+ * expected to be the context which created the view.
+ */
+void
+st_save_zombie_sampler_view(struct st_context *st,
+    struct pipe_sampler_view *view)
+{
+   struct st_zombie_sampler_view_node *entry;
+
+   assert(view->context == st->pipe);
+   assert(view->reference.count == 1);
+
+   entry = MALLOC_STRUCT(st_zombie_sampler_view_node);
+   if (!entry)
+  return;
+
+   entry->view = view;
+
+   /* We need a mutex since this function may be called from one thread
+    * while free_zombie_resource_views() is called from another.
+    */
+   mtx_lock(&st->zombie_sampler_views.mutex);
+   LIST_ADDTAIL(&entry->node, &st->zombie_sampler_views.list.node);
+   mtx_unlock(&st->zombie_sampler_views.mutex);
+}
+
+
+/*
+ * Free any zombie sampler views that may be attached to this context.
+ */
+static void
+free_zombie_sampler_views(struct st_context *st)
+{
+   struct st_zombie_sampler_view_node *entry, *next;
+
+   if (LIST_IS_EMPTY(&st->zombie_sampler_views.list.node)) {
+  return;
+   }
+
+   mtx_lock(&st->zombie_sampler_views.mutex);
+
+   LIST_FOR_EACH_ENTRY_SAFE(entry, next,
+    &st->zombie_sampler_views.list.node, node) {
+  LIST_DEL(&entry->node);  // remove this entry from the list
+
+  assert(entry->view->context == st->pipe);
+  assert(entry->view->reference.count == 1);
+  pipe_sampler_view_reference(&entry->view, NULL);
+
+  free(entry);
+   }
+
+   assert(LIST_IS_EMPTY(&st->zombie_sampler_views.list.node));
+
+   mtx_unlock(&st->zombie_sampler_views.mutex);
+}
+
+
+/*
+ * This function is called periodically to free any zombie objects
+ * which are attached to this context.
+ */
+void
+st_context_free_zombie_objects(struct st_context *st)
+{
+   free_zombie_sampler_views(st);
+}
+
+
  static void
  st_destroy_context_priv(struct st_context *st, bool de

Re: [Mesa-dev] [PATCH 1/8] st/mesa: implement "zombie" sampler views

2019-03-15 Thread Jose Fonseca

On 14/03/2019 19:37, Brian Paul wrote:

When st_texture_release_all_sampler_views() is called the texture may
have sampler views belonging to several contexts.  If we unreference a
sampler view and its refcount hits zero, we need to be sure to destroy
the sampler view with the same context which created it.

This was not the case with the previous code which used
pipe_sampler_view_release().  That function could end up freeing a
sampler view with a context different than the one which created it.
In the case of the VMware svga driver, we detected this but leaked the
sampler view.  This led to a crash with google-chrome when the kernel
module had too many sampler views.  VMware bug 2274734.

Alternately, if we try to delete a sampler view with the correct
context, we may be "reaching into" a context which is active on
another thread.  That's not safe.

To fix these issues this patch adds a per-context list of "zombie"
sampler views.  These are views which are to be freed at some point
when the context is active.  Other contexts may safely add sampler
views to the zombie list at any time (it's mutex protected).  This
avoids the context/view ownership mix-ups we had before.

Tested with: google-chrome, google earth, Redway3D Watch/Turbine demos
a few Linux games.  If anyone can recomment some other multi-threaded,
multi-context GL apps to test, please let me know.
---
  src/mesa/state_tracker/st_cb_flush.c |  6 +++
  src/mesa/state_tracker/st_context.c  | 81 
  src/mesa/state_tracker/st_context.h  | 25 ++
  src/mesa/state_tracker/st_sampler_view.c | 27 +--
  src/mesa/state_tracker/st_texture.h  |  3 ++
  5 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_flush.c 
b/src/mesa/state_tracker/st_cb_flush.c
index 5b3188c..81e5338 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -39,6 +39,7 @@
  #include "st_cb_flush.h"
  #include "st_cb_clear.h"
  #include "st_cb_fbo.h"
+#include "st_context.h"
  #include "st_manager.h"
  #include "pipe/p_context.h"
  #include "pipe/p_defines.h"
@@ -53,6 +54,11 @@ st_flush(struct st_context *st,
  {
 st_flush_bitmap_cache(st);
  
+   /* We want to call this function periodically.

+* Typically, it has nothing to do so it shouldn't be expensive.
+*/
+   st_context_free_zombie_objects(st);
+
 st->pipe->flush(st->pipe, fence, flags);
  }
  
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c

index 2898279..bd919da 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -261,6 +261,80 @@ st_invalidate_state(struct gl_context *ctx)
  }
  
  
+/*

+ * In some circumstances (such as running google-chrome) the state
+ * tracker may try to delete a resource view from a context different
+ * than when it was created.  We don't want to do that.
+ * In that situation, st_texture_release_all_sampler_views() calls this
+ * function to save the view for later deletion.  The context here is
+ * expected to be the context which created the view.
+ */
+void
+st_save_zombie_sampler_view(struct st_context *st,
+struct pipe_sampler_view *view)
+{
+   struct st_zombie_sampler_view_node *entry;
+
+   assert(view->context == st->pipe);
+   assert(view->reference.count == 1);
+
+   entry = MALLOC_STRUCT(st_zombie_sampler_view_node);
+   if (!entry)
+  return;
+
+   entry->view = view;
+
+   /* We need a mutex since this function may be called from one thread
+* while free_zombie_resource_views() is called from another.
+*/
+   mtx_lock(&st->zombie_sampler_views.mutex);
+   LIST_ADDTAIL(&entry->node, &st->zombie_sampler_views.list.node);
+   mtx_unlock(&st->zombie_sampler_views.mutex);
+}
+
+
+/*
+ * Free any zombie sampler views that may be attached to this context.
+ */
+static void
+free_zombie_sampler_views(struct st_context *st)
+{
+   struct st_zombie_sampler_view_node *entry, *next;
+
+   if (LIST_IS_EMPTY(&st->zombie_sampler_views.list.node)) {
+  return;
+   }
+
+   mtx_lock(&st->zombie_sampler_views.mutex);
+
+   LIST_FOR_EACH_ENTRY_SAFE(entry, next,
+&st->zombie_sampler_views.list.node, node) {
+  LIST_DEL(&entry->node);  // remove this entry from the list
+
+  assert(entry->view->context == st->pipe);
+  assert(entry->view->reference.count == 1);
+  pipe_sampler_view_reference(&entry->view, NULL);
+
+  free(entry);
+   }
+
+   assert(LIST_IS_EMPTY(&st->zombie_sampler_views.list.node));
+
+   mtx_unlock(&st->zombie_sampler_views.mutex);
+}
+
+
+/*
+ * This function is called periodically to free any zombie objects
+ * which are attached to this context.
+ */
+void
+st_context_free_zombie_objects(struct st_context *st)
+{
+   free_zombie_sampler_views(st);
+}
+
+
  static void
  st_destroy_context_priv(struct st_context *st, bool destroy_pipe)
  {
@@ -568,6 +642,9 @@

Re: [Mesa-dev] [PATCH 1/8] st/mesa: implement "zombie" sampler views

2019-03-14 Thread Mathias Fröhlich
Hi Brian,

the full package looks great and makes a lot of sense!

Reviewed-by: Mathias Fröhlich 

best

Mathias



On Thursday, 14 March 2019 20:37:09 CET Brian Paul wrote:
> When st_texture_release_all_sampler_views() is called the texture may
> have sampler views belonging to several contexts.  If we unreference a
> sampler view and its refcount hits zero, we need to be sure to destroy
> the sampler view with the same context which created it.
> 
> This was not the case with the previous code which used
> pipe_sampler_view_release().  That function could end up freeing a
> sampler view with a context different than the one which created it.
> In the case of the VMware svga driver, we detected this but leaked the
> sampler view.  This led to a crash with google-chrome when the kernel
> module had too many sampler views.  VMware bug 2274734.
> 
> Alternately, if we try to delete a sampler view with the correct
> context, we may be "reaching into" a context which is active on
> another thread.  That's not safe.
> 
> To fix these issues this patch adds a per-context list of "zombie"
> sampler views.  These are views which are to be freed at some point
> when the context is active.  Other contexts may safely add sampler
> views to the zombie list at any time (it's mutex protected).  This
> avoids the context/view ownership mix-ups we had before.
> 
> Tested with: google-chrome, google earth, Redway3D Watch/Turbine demos
> a few Linux games.  If anyone can recomment some other multi-threaded,
> multi-context GL apps to test, please let me know.
> ---
>  src/mesa/state_tracker/st_cb_flush.c |  6 +++
>  src/mesa/state_tracker/st_context.c  | 81 
> 
>  src/mesa/state_tracker/st_context.h  | 25 ++
>  src/mesa/state_tracker/st_sampler_view.c | 27 +--
>  src/mesa/state_tracker/st_texture.h  |  3 ++
>  5 files changed, 138 insertions(+), 4 deletions(-)
> 
> diff --git a/src/mesa/state_tracker/st_cb_flush.c 
> b/src/mesa/state_tracker/st_cb_flush.c
> index 5b3188c..81e5338 100644
> --- a/src/mesa/state_tracker/st_cb_flush.c
> +++ b/src/mesa/state_tracker/st_cb_flush.c
> @@ -39,6 +39,7 @@
>  #include "st_cb_flush.h"
>  #include "st_cb_clear.h"
>  #include "st_cb_fbo.h"
> +#include "st_context.h"
>  #include "st_manager.h"
>  #include "pipe/p_context.h"
>  #include "pipe/p_defines.h"
> @@ -53,6 +54,11 @@ st_flush(struct st_context *st,
>  {
> st_flush_bitmap_cache(st);
>  
> +   /* We want to call this function periodically.
> +* Typically, it has nothing to do so it shouldn't be expensive.
> +*/
> +   st_context_free_zombie_objects(st);
> +
> st->pipe->flush(st->pipe, fence, flags);
>  }
>  
> diff --git a/src/mesa/state_tracker/st_context.c 
> b/src/mesa/state_tracker/st_context.c
> index 2898279..bd919da 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -261,6 +261,80 @@ st_invalidate_state(struct gl_context *ctx)
>  }
>  
>  
> +/*
> + * In some circumstances (such as running google-chrome) the state
> + * tracker may try to delete a resource view from a context different
> + * than when it was created.  We don't want to do that.
> + * In that situation, st_texture_release_all_sampler_views() calls this
> + * function to save the view for later deletion.  The context here is
> + * expected to be the context which created the view.
> + */
> +void
> +st_save_zombie_sampler_view(struct st_context *st,
> +struct pipe_sampler_view *view)
> +{
> +   struct st_zombie_sampler_view_node *entry;
> +
> +   assert(view->context == st->pipe);
> +   assert(view->reference.count == 1);
> +
> +   entry = MALLOC_STRUCT(st_zombie_sampler_view_node);
> +   if (!entry)
> +  return;
> +
> +   entry->view = view;
> +
> +   /* We need a mutex since this function may be called from one thread
> +* while free_zombie_resource_views() is called from another.
> +*/
> +   mtx_lock(&st->zombie_sampler_views.mutex);
> +   LIST_ADDTAIL(&entry->node, &st->zombie_sampler_views.list.node);
> +   mtx_unlock(&st->zombie_sampler_views.mutex);
> +}
> +
> +
> +/*
> + * Free any zombie sampler views that may be attached to this context.
> + */
> +static void
> +free_zombie_sampler_views(struct st_context *st)
> +{
> +   struct st_zombie_sampler_view_node *entry, *next;
> +
> +   if (LIST_IS_EMPTY(&st->zombie_sampler_views.list.node)) {
> +  return;
> +   }
> +
> +   mtx_lock(&st->zombie_sampler_views.mutex);
> +
> +   LIST_FOR_EACH_ENTRY_SAFE(entry, next,
> +&st->zombie_sampler_views.list.node, node) {
> +  LIST_DEL(&entry->node);  // remove this entry from the list
> +
> +  assert(entry->view->context == st->pipe);
> +  assert(entry->view->reference.count == 1);
> +  pipe_sampler_view_reference(&entry->view, NULL);
> +
> +  free(entry);
> +   }
> +
> +   assert(LIST_IS_EMPTY(&st->zombie_sampler_views.list.node));
> +
> +   mtx_unlock(&s

[Mesa-dev] [PATCH 1/8] st/mesa: implement "zombie" sampler views

2019-03-14 Thread Brian Paul
When st_texture_release_all_sampler_views() is called the texture may
have sampler views belonging to several contexts.  If we unreference a
sampler view and its refcount hits zero, we need to be sure to destroy
the sampler view with the same context which created it.

This was not the case with the previous code which used
pipe_sampler_view_release().  That function could end up freeing a
sampler view with a context different than the one which created it.
In the case of the VMware svga driver, we detected this but leaked the
sampler view.  This led to a crash with google-chrome when the kernel
module had too many sampler views.  VMware bug 2274734.

Alternately, if we try to delete a sampler view with the correct
context, we may be "reaching into" a context which is active on
another thread.  That's not safe.

To fix these issues this patch adds a per-context list of "zombie"
sampler views.  These are views which are to be freed at some point
when the context is active.  Other contexts may safely add sampler
views to the zombie list at any time (it's mutex protected).  This
avoids the context/view ownership mix-ups we had before.

Tested with: google-chrome, google earth, Redway3D Watch/Turbine demos
a few Linux games.  If anyone can recomment some other multi-threaded,
multi-context GL apps to test, please let me know.
---
 src/mesa/state_tracker/st_cb_flush.c |  6 +++
 src/mesa/state_tracker/st_context.c  | 81 
 src/mesa/state_tracker/st_context.h  | 25 ++
 src/mesa/state_tracker/st_sampler_view.c | 27 +--
 src/mesa/state_tracker/st_texture.h  |  3 ++
 5 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_flush.c 
b/src/mesa/state_tracker/st_cb_flush.c
index 5b3188c..81e5338 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -39,6 +39,7 @@
 #include "st_cb_flush.h"
 #include "st_cb_clear.h"
 #include "st_cb_fbo.h"
+#include "st_context.h"
 #include "st_manager.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
@@ -53,6 +54,11 @@ st_flush(struct st_context *st,
 {
st_flush_bitmap_cache(st);
 
+   /* We want to call this function periodically.
+* Typically, it has nothing to do so it shouldn't be expensive.
+*/
+   st_context_free_zombie_objects(st);
+
st->pipe->flush(st->pipe, fence, flags);
 }
 
diff --git a/src/mesa/state_tracker/st_context.c 
b/src/mesa/state_tracker/st_context.c
index 2898279..bd919da 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -261,6 +261,80 @@ st_invalidate_state(struct gl_context *ctx)
 }
 
 
+/*
+ * In some circumstances (such as running google-chrome) the state
+ * tracker may try to delete a resource view from a context different
+ * than when it was created.  We don't want to do that.
+ * In that situation, st_texture_release_all_sampler_views() calls this
+ * function to save the view for later deletion.  The context here is
+ * expected to be the context which created the view.
+ */
+void
+st_save_zombie_sampler_view(struct st_context *st,
+struct pipe_sampler_view *view)
+{
+   struct st_zombie_sampler_view_node *entry;
+
+   assert(view->context == st->pipe);
+   assert(view->reference.count == 1);
+
+   entry = MALLOC_STRUCT(st_zombie_sampler_view_node);
+   if (!entry)
+  return;
+
+   entry->view = view;
+
+   /* We need a mutex since this function may be called from one thread
+* while free_zombie_resource_views() is called from another.
+*/
+   mtx_lock(&st->zombie_sampler_views.mutex);
+   LIST_ADDTAIL(&entry->node, &st->zombie_sampler_views.list.node);
+   mtx_unlock(&st->zombie_sampler_views.mutex);
+}
+
+
+/*
+ * Free any zombie sampler views that may be attached to this context.
+ */
+static void
+free_zombie_sampler_views(struct st_context *st)
+{
+   struct st_zombie_sampler_view_node *entry, *next;
+
+   if (LIST_IS_EMPTY(&st->zombie_sampler_views.list.node)) {
+  return;
+   }
+
+   mtx_lock(&st->zombie_sampler_views.mutex);
+
+   LIST_FOR_EACH_ENTRY_SAFE(entry, next,
+&st->zombie_sampler_views.list.node, node) {
+  LIST_DEL(&entry->node);  // remove this entry from the list
+
+  assert(entry->view->context == st->pipe);
+  assert(entry->view->reference.count == 1);
+  pipe_sampler_view_reference(&entry->view, NULL);
+
+  free(entry);
+   }
+
+   assert(LIST_IS_EMPTY(&st->zombie_sampler_views.list.node));
+
+   mtx_unlock(&st->zombie_sampler_views.mutex);
+}
+
+
+/*
+ * This function is called periodically to free any zombie objects
+ * which are attached to this context.
+ */
+void
+st_context_free_zombie_objects(struct st_context *st)
+{
+   free_zombie_sampler_views(st);
+}
+
+
 static void
 st_destroy_context_priv(struct st_context *st, bool destroy_pipe)
 {
@@ -568,6 +642,9 @@ st_create_context_priv(struct gl_context *ctx, struct 
pipe_contex