etnaviv: Make contexts track resources
authorMarek Vasut <marex@denx.de>
Sat, 8 Jun 2019 17:52:55 +0000 (19:52 +0200)
committerLucas Stach <dev@lynxeye.de>
Fri, 18 Oct 2019 17:03:25 +0000 (17:03 +0000)
Currently, the screen tracks all resources for all contexts, but this
is not correct. Each context should track the resources it uses. This
also allows a context to detect whether a resource is used by another
context and to notify another context using a resource that the current
context is done using the resource.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Christian Gmeiner <christian.gmeiner@gmail.com>
Cc: Guido G√ľnther <guido.gunther@puri.sm>
Cc: Lucas Stach <l.stach@pengutronix.de>
src/gallium/drivers/etnaviv/etnaviv_context.c
src/gallium/drivers/etnaviv/etnaviv_context.h
src/gallium/drivers/etnaviv/etnaviv_resource.c
src/gallium/drivers/etnaviv/etnaviv_screen.c
src/gallium/drivers/etnaviv/etnaviv_screen.h

index b31b1158303727c1ccf6252f59e8eaebfa2ed8a0..219d1de45f09ad7cfa75c5fca3d4c69d996948e2 100644 (file)
@@ -48,6 +48,7 @@
 
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
+#include "util/hash_table.h"
 #include "util/u_blitter.h"
 #include "util/u_helpers.h"
 #include "util/u_memory.h"
@@ -60,6 +61,25 @@ static void
 etna_context_destroy(struct pipe_context *pctx)
 {
    struct etna_context *ctx = etna_context(pctx);
+   struct etna_screen *screen = ctx->screen;
+
+   if (ctx->used_resources) {
+      mtx_lock(&screen->lock);
+
+      /*
+       * There should be no resources tracked in the context when it's being
+       * destroyed. Be sure there are none to avoid memory leaks on buggy
+       * programs.
+       */
+      set_foreach(ctx->used_resources, entry) {
+         struct etna_resource *rsc = (struct etna_resource *)entry->key;
+
+         _mesa_set_remove_key(rsc->pending_ctx, ctx);
+      }
+      _mesa_set_destroy(ctx->used_resources, NULL);
+
+      mtx_unlock(&screen->lock);
+   }
 
    if (ctx->dummy_rt)
       etna_bo_del(ctx->dummy_rt);
@@ -399,16 +419,18 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv)
    ctx->dirty_sampler_views = ~0L;
 
    /*
-    * Go through all _resources_ associated with this _screen_, pending
-    * in this _context_ and mark them as not pending in this _context_
-    * anymore, since they were just flushed.
+    * Go through all _resources_ pending in this _context_ and mark them as
+    * not pending in this _context_ anymore, since they were just flushed.
     */
    mtx_lock(&screen->lock);
-   set_foreach(screen->used_resources, entry) {
+   set_foreach(ctx->used_resources, entry) {
       struct etna_resource *rsc = (struct etna_resource *)entry->key;
 
+      rsc->status = 0;
+
       _mesa_set_remove_key(rsc->pending_ctx, ctx);
    }
+   _mesa_set_clear(ctx->used_resources, NULL);
    mtx_unlock(&screen->lock);
 }
 
@@ -447,6 +469,11 @@ etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    if (ctx->stream == NULL)
       goto fail;
 
+   ctx->used_resources = _mesa_set_create(NULL, _mesa_hash_pointer,
+                                          _mesa_key_pointer_equal);
+   if (!ctx->used_resources)
+      goto fail;
+
    /* context ctxate setup */
    ctx->specs = screen->specs;
    ctx->screen = screen;
index 81d4d963e058865f7c88e7b61b408be049760845..9fa6396dbb55506e772ad80e54e0caf3b117db53 100644 (file)
@@ -190,6 +190,9 @@ struct etna_context {
 
    struct etna_bo *dummy_rt;
    struct etna_reloc dummy_rt_reloc;
+
+   /* set of resources used by currently-unsubmitted renders */
+   struct set *used_resources;
 };
 
 static inline struct etna_context *
index 21943140f080b4f63c667cefeab5821bc6d58abb..3a58808d743fc8cac04afee33024ff5b102c9a0a 100644 (file)
@@ -468,7 +468,11 @@ etna_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc)
    struct etna_resource *rsc = etna_resource(prsc);
 
    mtx_lock(&screen->lock);
-   _mesa_set_remove_key(screen->used_resources, rsc);
+   set_foreach(rsc->pending_ctx, entry) {
+      struct etna_context *ctx = (struct etna_context *)entry->key;
+
+      _mesa_set_remove_key(rsc->pending_ctx, ctx);
+   }
    _mesa_set_destroy(rsc->pending_ctx, NULL);
    mtx_unlock(&screen->lock);
 
@@ -650,7 +654,7 @@ etna_resource_used(struct etna_context *ctx, struct pipe_resource *prsc,
 
    rsc->status |= status;
 
-   _mesa_set_add(screen->used_resources, rsc);
+   _mesa_set_add(ctx->used_resources, rsc);
    _mesa_set_add(rsc->pending_ctx, ctx);
 
    mtx_unlock(&screen->lock);
index 1476ab206f5ee43e413c7b817c75907af57560f0..ed989dbe149f4ddb0001d64003c3f665b8193ad0 100644 (file)
@@ -84,7 +84,6 @@ etna_screen_destroy(struct pipe_screen *pscreen)
 {
    struct etna_screen *screen = etna_screen(pscreen);
 
-   _mesa_set_destroy(screen->used_resources, NULL);
    mtx_destroy(&screen->lock);
 
    if (screen->perfmon)
@@ -958,15 +957,9 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
       etna_pm_query_setup(screen);
 
    mtx_init(&screen->lock, mtx_recursive);
-   screen->used_resources = _mesa_set_create(NULL, _mesa_hash_pointer,
-                                             _mesa_key_pointer_equal);
-   if (!screen->used_resources)
-      goto fail2;
 
    return pscreen;
 
-fail2:
-   mtx_destroy(&screen->lock);
 fail:
    etna_screen_destroy(pscreen);
    return NULL;
index 99e2cc20ac764596eb0d5169435fc68c4c1bef92..00d6989955f2e8d9c86407e39907c49d57b4b9c6 100644 (file)
@@ -85,9 +85,7 @@ struct etna_screen {
 
    uint32_t drm_version;
 
-   /* set of resources used by currently-unsubmitted renders */
    mtx_t lock;
-   struct set *used_resources;
 
    nir_shader_compiler_options options;
 };