iris: make resources take a ref on the screen object
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Fri, 6 Mar 2020 13:58:37 +0000 (15:58 +0200)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Sat, 11 Apr 2020 19:04:28 +0000 (22:04 +0300)
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 <lionel.g.landwerlin@intel.com>
Cc: <mesa-stable@lists.freedesktop.org>
Closes: https://gitlab.freedesktop.org/mesa/mesa/issues/1373
Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Rafael Antognolli <rafael.antognolli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4086>

src/gallium/drivers/iris/iris_resource.c
src/gallium/drivers/iris/iris_screen.c
src/gallium/drivers/iris/iris_screen.h

index 50f01d350cfc54eaba0ac063d7fb0afebc4ba59d..40655bb4032ba5e4990b36c5dc9e520ab26a267d 100644 (file)
@@ -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;
index 6afd1235f8ca10147119dbfaad00d919bebdf145..0c99e3702e28b10602c4b25ad0ed74f649b3f1ea 100644 (file)
@@ -521,17 +521,22 @@ 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;
index cd5bac9e54ec4b700cb9b3abefd2079f6f0c4221..58864f7625d4689aba56baf98548b9a909eb4ab2 100644 (file)
@@ -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,