st/mesa: don't leak pipe_surface if pipe_context is not current
authorMarek Olšák <marek.olsak@amd.com>
Tue, 8 Jan 2019 16:12:05 +0000 (11:12 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 9 Jan 2019 16:08:44 +0000 (11:08 -0500)
We have found some pipe_surface leaks internally.

This is the same code as surface_destroy in radeonsi.
Ideally, surface_destroy would be in pipe_screen.

Cc: 18.3 <mesa-stable@lists.freedesktop.org>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/util/u_inlines.h
src/mesa/state_tracker/st_cb_fbo.c

index b06fb111709f20535af53c11bda24d9080522a0e..fa1e920b509fa55356ffa3117a439f48523fbb19 100644 (file)
@@ -154,6 +154,25 @@ pipe_resource_reference(struct pipe_resource **dst, struct pipe_resource *src)
    *dst = src;
 }
 
+/**
+ * Same as pipe_surface_release, but used when pipe_context doesn't exist
+ * anymore.
+ */
+static inline void
+pipe_surface_release_no_context(struct pipe_surface **ptr)
+{
+   struct pipe_surface *surf = *ptr;
+
+   if (pipe_reference_described(&surf->reference, NULL,
+                                (debug_reference_descriptor)
+                                debug_describe_surface)) {
+      /* trivially destroy pipe_surface */
+      pipe_resource_reference(&surf->texture, NULL);
+      free(surf);
+   }
+   *ptr = NULL;
+}
+
 /**
  * Set *dst to \p src with proper reference counting.
  *
index 8901a8680efc8afb2820d1a338c4c9a23348fa65..8d099f7b0f97e94983bc65a31cb92c447bdee649 100644 (file)
@@ -285,8 +285,11 @@ st_renderbuffer_delete(struct gl_context *ctx, struct gl_renderbuffer *rb)
       struct st_context *st = st_context(ctx);
       pipe_surface_release(st->pipe, &strb->surface_srgb);
       pipe_surface_release(st->pipe, &strb->surface_linear);
-      strb->surface = NULL;
+   } else {
+      pipe_surface_release_no_context(&strb->surface_srgb);
+      pipe_surface_release_no_context(&strb->surface_linear);
    }
+   strb->surface = NULL;
    pipe_resource_reference(&strb->texture, NULL);
    free(strb->data);
    _mesa_delete_renderbuffer(ctx, rb);