diff --git a/backend/backend.c b/backend/backend.c index ec309da4..359df3d1 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -91,15 +91,9 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) { return NULL; } - int gpu = wlr_session_find_gpu(session); - if (gpu == -1) { - wlr_log(L_ERROR, "Failed to open DRM device"); - goto error_session; - } - backend = wlr_multi_backend_create(session); if (!backend) { - goto error_gpu; + goto error_session; } struct wlr_backend *libinput = wlr_libinput_backend_create(display, session); @@ -107,21 +101,36 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) { goto error_multi; } - struct wlr_backend *drm = wlr_drm_backend_create(display, session, gpu); - if (!drm) { - goto error_libinput; + wlr_multi_backend_add(backend, libinput); + + int gpus[8]; + size_t num_gpus = wlr_session_find_gpus(session, 8, gpus); + struct wlr_backend *primary_drm = NULL; + wlr_log(L_INFO, "Found %zu GPUs", num_gpus); + + for (size_t i = 0; i < num_gpus; ++i) { + struct wlr_backend *drm = wlr_drm_backend_create(display, session, gpus[i]); + if (!drm) { + wlr_log(L_ERROR, "Failed to open DRM device"); + continue; + } + + if (!primary_drm) { + primary_drm = drm; + } + + wlr_multi_backend_add(backend, drm); + } + + if (!primary_drm) { + wlr_log(L_ERROR, "Failed to open any DRM device"); + goto error_multi; } - wlr_multi_backend_add(backend, libinput); - wlr_multi_backend_add(backend, drm); return backend; -error_libinput: - wlr_backend_destroy(libinput); error_multi: wlr_backend_destroy(backend); -error_gpu: - wlr_session_close_file(session, gpu); error_session: wlr_session_destroy(session); return NULL; diff --git a/backend/drm/backend.c b/backend/drm/backend.c index 442e5d0e..2d06e5e4 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -42,8 +42,8 @@ static void wlr_drm_backend_destroy(struct wlr_backend *backend) { free(drm); } -static struct wlr_egl *wlr_drm_backend_get_egl(struct wlr_backend *_backend) { - struct wlr_drm_backend *drm = (struct wlr_drm_backend *)_backend; +static struct wlr_egl *wlr_drm_backend_get_egl(struct wlr_backend *backend) { + struct wlr_drm_backend *drm = (struct wlr_drm_backend *)backend; return &drm->renderer.egl; } diff --git a/backend/session/session.c b/backend/session/session.c index cfa617f6..be79c34d 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -191,18 +191,16 @@ bool wlr_session_change_vt(struct wlr_session *session, unsigned vt) { /* Tests if 'path' is KMS compatible by trying to open it. * It leaves the open device in *fd_out it it succeeds. */ -static bool device_is_kms(struct wlr_session *restrict session, - const char *restrict path, int *restrict fd_out) { - +static int open_if_kms(struct wlr_session *restrict session, const char *restrict path) { int fd; if (!path) { - return false; + return -1; } fd = wlr_session_open_file(session, path); if (fd < 0) { - return false; + return -1; } drmModeRes *res = drmModeGetResources(fd); @@ -216,26 +214,21 @@ static bool device_is_kms(struct wlr_session *restrict session, goto out_res; } - if (*fd_out >= 0) { - wlr_session_close_file(session, *fd_out); - } - - *fd_out = fd; - drmModeFreeResources(res); - return true; + return fd; out_res: drmModeFreeResources(res); out_fd: wlr_session_close_file(session, fd); - return false; + return -1; } /* Tries to find the primary GPU by checking for the "boot_vga" attribute. * If it's not found, it returns the first valid GPU it finds. */ -int wlr_session_find_gpu(struct wlr_session *session) { +size_t wlr_session_find_gpus(struct wlr_session *session, + size_t ret_len, int ret[static ret_len]) { struct udev_enumerate *en = udev_enumerate_new(session->udev); if (!en) { wlr_log(L_ERROR, "Failed to create udev enumeration"); @@ -247,9 +240,13 @@ int wlr_session_find_gpu(struct wlr_session *session) { udev_enumerate_scan_devices(en); struct udev_list_entry *entry; - int fd = -1; + size_t i = 0; udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(en)) { + if (i == ret_len) { + break; + } + bool is_boot_vga = false; const char *path = udev_list_entry_get_name(entry); @@ -258,15 +255,13 @@ int wlr_session_find_gpu(struct wlr_session *session) { continue; } - /* const char *seat = udev_device_get_property_value(dev, "ID_SEAT"); if (!seat) seat = "seat0"; - if (strcmp(session->seat, seat) != 0) { + if (session->seat[0] && strcmp(session->seat, seat) != 0) { udev_device_unref(dev); continue; } - */ // This is owned by 'dev', so we don't need to free it struct udev_device *pci = @@ -279,27 +274,25 @@ int wlr_session_find_gpu(struct wlr_session *session) { } } - // We already have a valid GPU - if (!is_boot_vga && fd >= 0) { - udev_device_unref(dev); - continue; - } - - path = udev_device_get_devnode(dev); - if (!device_is_kms(session, path, &fd)) { + int fd = open_if_kms(session, udev_device_get_devnode(dev)); + if (fd < 0) { udev_device_unref(dev); continue; } udev_device_unref(dev); - // We've found the primary GPU + ret[i] = fd; if (is_boot_vga) { - break; + int tmp = ret[0]; + ret[0] = ret[i]; + ret[i] = tmp; } + + ++i; } udev_enumerate_unref(en); - return fd; + return i; } diff --git a/include/wlr/backend/session.h b/include/wlr/backend/session.h index 52cf13b7..94002bc5 100644 --- a/include/wlr/backend/session.h +++ b/include/wlr/backend/session.h @@ -72,12 +72,13 @@ int wlr_session_open_file(struct wlr_session *session, const char *path); void wlr_session_close_file(struct wlr_session *session, int fd); void wlr_session_signal_add(struct wlr_session *session, int fd, - struct wl_listener *listener); + struct wl_listener *listener); /* * Changes the virtual terminal. */ bool wlr_session_change_vt(struct wlr_session *session, unsigned vt); -int wlr_session_find_gpu(struct wlr_session *session); +size_t wlr_session_find_gpus(struct wlr_session *session, + size_t ret_len, int ret[static ret_len]); #endif