From f9e72b7fcbf390805070b10cf21dec12f45c9445 Mon Sep 17 00:00:00 2001 From: Mary Guillemard Date: Tue, 15 Oct 2024 23:16:31 +0200 Subject: [PATCH] winsys/nouveau: Rework to use u_pipe_screen_lookup_or_create All the boilerplate can be removed to use u_pipe_screen_lookup_or_create instead. Signed-off-by: Mary Guillemard Reviewed-by: Karol Herbst Part-of: --- src/gallium/drivers/nouveau/nouveau_screen.c | 7 +- src/gallium/drivers/nouveau/nouveau_screen.h | 4 +- .../drivers/nouveau/nv30/nv30_screen.c | 2 +- .../drivers/nouveau/nv50/nv50_screen.c | 2 +- .../drivers/nouveau/nvc0/nvc0_screen.c | 2 +- .../winsys/nouveau/drm/nouveau_drm_public.h | 2 + .../winsys/nouveau/drm/nouveau_drm_winsys.c | 118 +++++------------- 7 files changed, 41 insertions(+), 96 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index d178fbdc3c3..be5934c92ed 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -317,12 +317,7 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) */ screen->drm = nouveau_drm(&dev->object); screen->device = dev; - - /* - * this is initialized to 1 in nouveau_drm_screen_create after screen - * is fully constructed and added to the global screen list. - */ - screen->refcount = -1; + screen->initialized = false; if (dev->chipset < 0xc0) { data = &nv04_data; diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index cae9a733f7f..ab16eae72e1 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -32,7 +32,7 @@ struct nouveau_screen { char chipset_name[8]; - int refcount; + bool initialized; unsigned transfer_pushbuf_threshold; @@ -137,8 +137,6 @@ nouveau_screen(struct pipe_screen *pscreen) return (struct nouveau_screen *)pscreen; } -bool nouveau_drm_screen_unref(struct nouveau_screen *screen); - bool nouveau_screen_bo_get_handle(struct pipe_screen *pscreen, struct nouveau_bo *bo, diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index 3b1d183d80b..f262e84c2bf 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -534,7 +534,7 @@ nv30_screen_destroy(struct pipe_screen *pscreen) { struct nv30_screen *screen = nv30_screen(pscreen); - if (!nouveau_drm_screen_unref(&screen->base)) + if (!screen->base.initialized) return; nouveau_bo_ref(NULL, &screen->notify); diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 6cdd223eb1f..cf9d06eb435 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -472,7 +472,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen) { struct nv50_screen *screen = nv50_screen(pscreen); - if (!nouveau_drm_screen_unref(&screen->base)) + if (!screen->base.initialized) return; if (screen->blitter) diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index c696c230355..62ae898f30e 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -608,7 +608,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) { struct nvc0_screen *screen = nvc0_screen(pscreen); - if (!nouveau_drm_screen_unref(&screen->base)) + if (!screen->base.initialized) return; if (screen->blitter) diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_public.h b/src/gallium/winsys/nouveau/drm/nouveau_drm_public.h index 67b7c4429df..a095f6510b8 100644 --- a/src/gallium/winsys/nouveau/drm/nouveau_drm_public.h +++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_public.h @@ -3,6 +3,8 @@ #define __NOUVEAU_DRM_PUBLIC_H__ struct pipe_screen; +struct pipe_screen_config; +struct renderonly; struct pipe_screen *nouveau_drm_screen_create(int drmFD); diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c index cf12df9eacd..7aab74572ad 100644 --- a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c +++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c @@ -1,87 +1,34 @@ -#include #include -#include -#include "pipe/p_context.h" -#include "pipe/p_state.h" + #include "util/format/u_format.h" #include "util/os_file.h" -#include "util/simple_mtx.h" +#include "util/u_debug.h" #include "util/u_memory.h" -#include "util/u_inlines.h" -#include "util/u_hash_table.h" -#include "util/u_pointer.h" -#include "util/u_thread.h" +#include "util/u_screen.h" +#include "renderonly/renderonly.h" #include "nouveau_drm_public.h" #include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_screen.h" -#include "nvif/class.h" -#include "nvif/cl0080.h" - -static struct hash_table *fd_tab = NULL; - -static simple_mtx_t nouveau_screen_mutex = SIMPLE_MTX_INITIALIZER; - -bool nouveau_drm_screen_unref(struct nouveau_screen *screen) -{ - int ret; - if (screen->refcount == -1) - return true; - - simple_mtx_lock(&nouveau_screen_mutex); - ret = --screen->refcount; - assert(ret >= 0); - if (ret == 0) - _mesa_hash_table_remove_key(fd_tab, intptr_to_pointer(screen->drm->fd)); - simple_mtx_unlock(&nouveau_screen_mutex); - return ret == 0; -} - -PUBLIC struct pipe_screen * -nouveau_drm_screen_create(int fd) +static struct pipe_screen * +nouveau_screen_create(int fd, const struct pipe_screen_config *config, + struct renderonly *ro) { struct nouveau_drm *drm = NULL; struct nouveau_device *dev = NULL; struct nouveau_screen *(*init)(struct nouveau_device *); struct nouveau_screen *screen = NULL; - int ret, dupfd; + int ret; - simple_mtx_lock(&nouveau_screen_mutex); - if (!fd_tab) { - fd_tab = util_hash_table_create_fd_keys(); - if (!fd_tab) { - simple_mtx_unlock(&nouveau_screen_mutex); - return NULL; - } - } - - screen = util_hash_table_get(fd_tab, intptr_to_pointer(fd)); - if (screen) { - screen->refcount++; - simple_mtx_unlock(&nouveau_screen_mutex); - return &screen->base; - } - - /* Since the screen re-use is based on the device node and not the fd, - * create a copy of the fd to be owned by the device. Otherwise a - * scenario could occur where two screens are created, and the first - * one is shut down, along with the fd being closed. The second - * (identical) screen would now have a reference to the closed fd. We - * avoid this by duplicating the original fd. Note that - * nouveau_device_wrap does not close the fd in case of a device - * creation error. - */ - dupfd = os_dupfd_cloexec(fd); - - ret = nouveau_drm_new(dupfd, &drm); + ret = nouveau_drm_new(fd, &drm); if (ret) - goto err; + return NULL; ret = nouveau_device_new(&drm->client, &dev); if (ret) - goto err; + goto err_dev_new; switch (dev->chipset & ~0xf) { case 0x30: @@ -111,31 +58,34 @@ nouveau_drm_screen_create(int fd) break; default: debug_printf("%s: unknown chipset nv%02x\n", __func__, - dev->chipset); - goto err; + dev->chipset); + goto err_screen_create; } screen = init(dev); - if (!screen || !screen->base.context_create) - goto err; + if (!screen) + goto err_screen_create; - /* Use dupfd in hash table, to avoid errors if the original fd gets - * closed by its owner. The hash key needs to live at least as long as - * the screen. - */ - _mesa_hash_table_insert(fd_tab, intptr_to_pointer(dupfd), screen); - screen->refcount = 1; - simple_mtx_unlock(&nouveau_screen_mutex); + if (!screen->base.context_create) + goto err_screen_init; + + screen->initialized = true; return &screen->base; -err: - if (screen) { - screen->base.destroy(&screen->base); - } else { - nouveau_device_del(&dev); - nouveau_drm_del(&drm); - close(dupfd); - } - simple_mtx_unlock(&nouveau_screen_mutex); +err_screen_init: + screen->base.destroy(&screen->base); + return NULL; + +err_screen_create: + nouveau_device_del(&dev); +err_dev_new: + nouveau_drm_del(&drm); return NULL; } + +PUBLIC struct pipe_screen * +nouveau_drm_screen_create(int fd) +{ + return u_pipe_screen_lookup_or_create(os_dupfd_cloexec(fd), NULL, NULL, + nouveau_screen_create); +}