From 90e223646bf9541c4b751bcbd04cd81e27fb42e1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 8 Jun 2019 19:52:55 +0200 Subject: [PATCH] etnaviv: Make contexts track resources MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Cc: Christian Gmeiner Cc: Guido Günther Cc: Lucas Stach --- src/gallium/drivers/etnaviv/etnaviv_context.c | 35 ++++++++++++++++--- src/gallium/drivers/etnaviv/etnaviv_context.h | 3 ++ .../drivers/etnaviv/etnaviv_resource.c | 8 +++-- src/gallium/drivers/etnaviv/etnaviv_screen.c | 7 ---- src/gallium/drivers/etnaviv/etnaviv_screen.h | 2 -- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index b31b1158303..219d1de45f0 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -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; diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.h b/src/gallium/drivers/etnaviv/etnaviv_context.h index 81d4d963e05..9fa6396dbb5 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.h +++ b/src/gallium/drivers/etnaviv/etnaviv_context.h @@ -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 * diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index 21943140f08..3a58808d743 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -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); diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c index 1476ab206f5..ed989dbe149 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -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; diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.h b/src/gallium/drivers/etnaviv/etnaviv_screen.h index 99e2cc20ac7..00d6989955f 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.h +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.h @@ -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; }; -- 2.30.2