Change wlr_session to open every GPU
This commit is contained in:
		
							parent
							
								
									eaef028976
								
							
						
					
					
						commit
						fa3d0ed929
					
				| 
						 | 
					@ -91,15 +91,9 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
 | 
				
			||||||
		return NULL;
 | 
							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);
 | 
						backend = wlr_multi_backend_create(session);
 | 
				
			||||||
	if (!backend) {
 | 
						if (!backend) {
 | 
				
			||||||
		goto error_gpu;
 | 
							goto error_session;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_backend *libinput = wlr_libinput_backend_create(display, 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;
 | 
							goto error_multi;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_backend *drm = wlr_drm_backend_create(display, session, gpu);
 | 
						wlr_multi_backend_add(backend, libinput);
 | 
				
			||||||
	if (!drm) {
 | 
					
 | 
				
			||||||
		goto error_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;
 | 
						return backend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_libinput:
 | 
					 | 
				
			||||||
	wlr_backend_destroy(libinput);
 | 
					 | 
				
			||||||
error_multi:
 | 
					error_multi:
 | 
				
			||||||
	wlr_backend_destroy(backend);
 | 
						wlr_backend_destroy(backend);
 | 
				
			||||||
error_gpu:
 | 
					 | 
				
			||||||
	wlr_session_close_file(session, gpu);
 | 
					 | 
				
			||||||
error_session:
 | 
					error_session:
 | 
				
			||||||
	wlr_session_destroy(session);
 | 
						wlr_session_destroy(session);
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,8 +42,8 @@ static void wlr_drm_backend_destroy(struct wlr_backend *backend) {
 | 
				
			||||||
	free(drm);
 | 
						free(drm);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_egl *wlr_drm_backend_get_egl(struct wlr_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;
 | 
						struct wlr_drm_backend *drm = (struct wlr_drm_backend *)backend;
 | 
				
			||||||
	return &drm->renderer.egl;
 | 
						return &drm->renderer.egl;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.
 | 
					/* Tests if 'path' is KMS compatible by trying to open it.
 | 
				
			||||||
 * It leaves the open device in *fd_out it it succeeds.
 | 
					 * It leaves the open device in *fd_out it it succeeds.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static bool device_is_kms(struct wlr_session *restrict session,
 | 
					static int open_if_kms(struct wlr_session *restrict session, const char *restrict path) {
 | 
				
			||||||
	const char *restrict path, int *restrict fd_out) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!path) {
 | 
						if (!path) {
 | 
				
			||||||
		return false;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fd = wlr_session_open_file(session, path);
 | 
						fd = wlr_session_open_file(session, path);
 | 
				
			||||||
	if (fd < 0) {
 | 
						if (fd < 0) {
 | 
				
			||||||
		return false;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drmModeRes *res = drmModeGetResources(fd);
 | 
						drmModeRes *res = drmModeGetResources(fd);
 | 
				
			||||||
| 
						 | 
					@ -216,26 +214,21 @@ static bool device_is_kms(struct wlr_session *restrict session,
 | 
				
			||||||
		goto out_res;
 | 
							goto out_res;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (*fd_out >= 0) {
 | 
					 | 
				
			||||||
		wlr_session_close_file(session, *fd_out);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*fd_out = fd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	drmModeFreeResources(res);
 | 
						drmModeFreeResources(res);
 | 
				
			||||||
	return true;
 | 
						return fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_res:
 | 
					out_res:
 | 
				
			||||||
	drmModeFreeResources(res);
 | 
						drmModeFreeResources(res);
 | 
				
			||||||
out_fd:
 | 
					out_fd:
 | 
				
			||||||
	wlr_session_close_file(session, fd);
 | 
						wlr_session_close_file(session, fd);
 | 
				
			||||||
	return false;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Tries to find the primary GPU by checking for the "boot_vga" attribute.
 | 
					/* 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.
 | 
					 * 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);
 | 
						struct udev_enumerate *en = udev_enumerate_new(session->udev);
 | 
				
			||||||
	if (!en) {
 | 
						if (!en) {
 | 
				
			||||||
		wlr_log(L_ERROR, "Failed to create udev enumeration");
 | 
							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);
 | 
						udev_enumerate_scan_devices(en);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct udev_list_entry *entry;
 | 
						struct udev_list_entry *entry;
 | 
				
			||||||
	int fd = -1;
 | 
						size_t i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(en)) {
 | 
						udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(en)) {
 | 
				
			||||||
 | 
							if (i == ret_len) {
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool is_boot_vga = false;
 | 
							bool is_boot_vga = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const char *path = udev_list_entry_get_name(entry);
 | 
							const char *path = udev_list_entry_get_name(entry);
 | 
				
			||||||
| 
						 | 
					@ -258,15 +255,13 @@ int wlr_session_find_gpu(struct wlr_session *session) {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		const char *seat = udev_device_get_property_value(dev, "ID_SEAT");
 | 
							const char *seat = udev_device_get_property_value(dev, "ID_SEAT");
 | 
				
			||||||
		if (!seat)
 | 
							if (!seat)
 | 
				
			||||||
			seat = "seat0";
 | 
								seat = "seat0";
 | 
				
			||||||
		if (strcmp(session->seat, seat) != 0) {
 | 
							if (session->seat[0] && strcmp(session->seat, seat) != 0) {
 | 
				
			||||||
			udev_device_unref(dev);
 | 
								udev_device_unref(dev);
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		*/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// This is owned by 'dev', so we don't need to free it
 | 
							// This is owned by 'dev', so we don't need to free it
 | 
				
			||||||
		struct udev_device *pci =
 | 
							struct udev_device *pci =
 | 
				
			||||||
| 
						 | 
					@ -279,27 +274,25 @@ int wlr_session_find_gpu(struct wlr_session *session) {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// We already have a valid GPU
 | 
							int fd = open_if_kms(session, udev_device_get_devnode(dev));
 | 
				
			||||||
		if (!is_boot_vga && fd >= 0) {
 | 
							if (fd < 0) {
 | 
				
			||||||
			udev_device_unref(dev);
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		path = udev_device_get_devnode(dev);
 | 
					 | 
				
			||||||
		if (!device_is_kms(session, path, &fd)) {
 | 
					 | 
				
			||||||
			udev_device_unref(dev);
 | 
								udev_device_unref(dev);
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		udev_device_unref(dev);
 | 
							udev_device_unref(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// We've found the primary GPU
 | 
							ret[i] = fd;
 | 
				
			||||||
		if (is_boot_vga) {
 | 
							if (is_boot_vga) {
 | 
				
			||||||
			break;
 | 
								int tmp = ret[0];
 | 
				
			||||||
 | 
								ret[0] = ret[i];
 | 
				
			||||||
 | 
								ret[i] = tmp;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							++i;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	udev_enumerate_unref(en);
 | 
						udev_enumerate_unref(en);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return fd;
 | 
						return i;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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_close_file(struct wlr_session *session, int fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_session_signal_add(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.
 | 
					 * Changes the virtual terminal.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool wlr_session_change_vt(struct wlr_session *session, unsigned vt);
 | 
					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
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue