aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLionel Landwerlin <[email protected]>2020-03-06 15:58:37 +0200
committerLionel Landwerlin <[email protected]>2020-04-11 22:04:28 +0300
commit0a497eb1303d23f04ad7d9c28abf953a9105e32a (patch)
treec137738d9aa1ab23108d69ae30d761f6c714a86f
parent7557f1605968c39d680545d5b8457d17eea3b922 (diff)
iris: make resources take a ref on the screen object
Because St creates resources from a screen and attach them onto another we need to ensure the resources associated to a screen & bufmgr stay around until we don't need them anymore. Signed-off-by: Lionel Landwerlin <[email protected]> Cc: <[email protected]> Closes: https://gitlab.freedesktop.org/mesa/mesa/issues/1373 Reviewed-by: Adam Jackson <[email protected]> Reviewed-by: Rafael Antognolli <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4086>
-rw-r--r--src/gallium/drivers/iris/iris_resource.c4
-rw-r--r--src/gallium/drivers/iris/iris_screen.c17
-rw-r--r--src/gallium/drivers/iris/iris_screen.h22
3 files changed, 37 insertions, 6 deletions
diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index 50f01d350cf..40655bb4032 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -340,6 +340,8 @@ iris_resource_destroy(struct pipe_screen *screen,
iris_resource_disable_aux(res);
iris_bo_unreference(res->bo);
+ iris_pscreen_unref(res->base.screen);
+
free(res);
}
@@ -352,7 +354,7 @@ iris_alloc_resource(struct pipe_screen *pscreen,
return NULL;
res->base = *templ;
- res->base.screen = pscreen;
+ res->base.screen = iris_pscreen_ref(pscreen);
pipe_reference_init(&res->base.reference, 1);
res->aux.possible_usages = 1 << ISL_AUX_USAGE_NONE;
diff --git a/src/gallium/drivers/iris/iris_screen.c b/src/gallium/drivers/iris/iris_screen.c
index 6afd1235f8c..0c99e3702e2 100644
--- a/src/gallium/drivers/iris/iris_screen.c
+++ b/src/gallium/drivers/iris/iris_screen.c
@@ -521,18 +521,23 @@ iris_get_timestamp(struct pipe_screen *pscreen)
return result;
}
-static void
-iris_destroy_screen(struct pipe_screen *pscreen)
+void
+iris_screen_destroy(struct iris_screen *screen)
{
- struct iris_screen *screen = (struct iris_screen *) pscreen;
iris_bo_unreference(screen->workaround_bo);
- u_transfer_helper_destroy(pscreen->transfer_helper);
+ u_transfer_helper_destroy(screen->base.transfer_helper);
iris_bufmgr_unref(screen->bufmgr);
disk_cache_destroy(screen->disk_cache);
ralloc_free(screen);
}
static void
+iris_screen_unref(struct pipe_screen *pscreen)
+{
+ iris_pscreen_unref(pscreen);
+}
+
+static void
iris_query_memory_info(struct pipe_screen *pscreen,
struct pipe_memory_info *info)
{
@@ -639,6 +644,8 @@ iris_screen_create(int fd, const struct pipe_screen_config *config)
screen->pci_id = screen->devinfo.chipset_id;
screen->no_hw = screen->devinfo.no_hw;
+ p_atomic_set(&screen->refcount, 1);
+
if (screen->devinfo.gen < 8 || screen->devinfo.is_cherryview)
return NULL;
@@ -705,7 +712,7 @@ iris_screen_create(int fd, const struct pipe_screen_config *config)
iris_init_screen_fence_functions(pscreen);
iris_init_screen_resource_functions(pscreen);
- pscreen->destroy = iris_destroy_screen;
+ pscreen->destroy = iris_screen_unref;
pscreen->get_name = iris_get_name;
pscreen->get_vendor = iris_get_vendor;
pscreen->get_device_vendor = iris_get_device_vendor;
diff --git a/src/gallium/drivers/iris/iris_screen.h b/src/gallium/drivers/iris/iris_screen.h
index cd5bac9e54e..58864f7625d 100644
--- a/src/gallium/drivers/iris/iris_screen.h
+++ b/src/gallium/drivers/iris/iris_screen.h
@@ -46,6 +46,8 @@ struct gen_l3_config;
struct iris_screen {
struct pipe_screen base;
+ uint32_t refcount;
+
/** Global slab allocator for iris_transfer_map objects */
struct slab_parent_pool transfer_pool;
@@ -96,6 +98,26 @@ struct iris_screen {
struct pipe_screen *
iris_screen_create(int fd, const struct pipe_screen_config *config);
+void iris_screen_destroy(struct iris_screen *screen);
+
+UNUSED static inline struct pipe_screen *
+iris_pscreen_ref(struct pipe_screen *pscreen)
+{
+ struct iris_screen *screen = (struct iris_screen *) pscreen;
+
+ p_atomic_inc(&screen->refcount);
+ return pscreen;
+}
+
+UNUSED static inline void
+iris_pscreen_unref(struct pipe_screen *pscreen)
+{
+ struct iris_screen *screen = (struct iris_screen *) pscreen;
+
+ if (p_atomic_dec_zero(&screen->refcount))
+ iris_screen_destroy(screen);
+}
+
bool
iris_is_format_supported(struct pipe_screen *pscreen,
enum pipe_format format,