On Mon, Oct 29, 2012 at 07:21:16PM +0100, David Herrmann wrote: > If we can find a boot_vga PCI GPU, we should prefer it over any other GPU > that is connected to the system. The boot_vga flag tells us that this GPU > is the primary system GPU. > > This fixes problems on two-GPU-systems were the wrong GPU is used. It also > fixes systems were DisplayLink GPUs are available with lower IDs than PCI > GPUs (although, this seems unlikely). > > Note that udev_enumerate guarantees that the entry-list is sorted. So for > systems that have platform-GPUs, these should almost always be reported > prior to hotpluggable (PCI, USB, ...) GPUs, as the kernel probes them > first.
That looks good, definitely an improvement over what we have now. If/when we start supporting multiple GPUs and/or DisplayLink devices, we'll figure what the next step looks like. Kristian > Signed-off-by: David Herrmann <[email protected]> > --- > src/compositor-drm.c | 90 > ++++++++++++++++++++++++++++++++++++---------------- > 1 file changed, 62 insertions(+), 28 deletions(-) > > diff --git a/src/compositor-drm.c b/src/compositor-drm.c > index 3e75387..1730cb2 100644 > --- a/src/compositor-drm.c > +++ b/src/compositor-drm.c > @@ -2148,18 +2148,72 @@ switch_vt_binding(struct wl_seat *seat, uint32_t > time, uint32_t key, void *data) > tty_activate_vt(ec->tty, key - KEY_F1 + 1); > } > > +/* > + * Find primary GPU > + * Some systems may have multiple DRM devices attached to a single seat. This > + * function loops over all devices and tries to find a PCI device with the > + * boot_vga sysfs attribute set to 1. > + * If no such device is found, the first DRM device reported by udev is used. > + */ > +static struct udev_device* > +find_primary_gpu(struct drm_compositor *ec, const char *seat) > +{ > + struct udev_enumerate *e; > + struct udev_list_entry *entry; > + const char *path, *device_seat, *id; > + struct udev_device *device, *drm_device, *pci; > + > + e = udev_enumerate_new(ec->udev); > + udev_enumerate_add_match_subsystem(e, "drm"); > + udev_enumerate_add_match_sysname(e, "card[0-9]*"); > + > + udev_enumerate_scan_devices(e); > + drm_device = NULL; > + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) { > + path = udev_list_entry_get_name(entry); > + device = udev_device_new_from_syspath(ec->udev, path); > + if (!device) > + continue; > + device_seat = udev_device_get_property_value(device, "ID_SEAT"); > + if (!device_seat) > + device_seat = default_seat; > + if (strcmp(device_seat, seat)) { > + udev_device_unref(device); > + continue; > + } > + > + pci = udev_device_get_parent_with_subsystem_devtype(device, > + "pci", NULL); > + if (pci) { > + id = udev_device_get_sysattr_value(pci, "boot_vga"); > + if (id && !strcmp(id, "1")) { > + if (drm_device) > + udev_device_unref(drm_device); > + drm_device = device; > + break; > + } > + } > + > + if (!drm_device) > + drm_device = device; > + else > + udev_device_unref(device); > + } > + > + udev_enumerate_unref(e); > + return drm_device; > +} > + > static struct weston_compositor * > drm_compositor_create(struct wl_display *display, > int connector, const char *seat, int tty, > int argc, char *argv[], const char *config_file) > { > struct drm_compositor *ec; > - struct udev_enumerate *e; > - struct udev_list_entry *entry; > - struct udev_device *device, *drm_device; > - const char *path, *device_seat; > + struct udev_device *drm_device; > struct wl_event_loop *loop; > struct weston_seat *weston_seat, *next; > + const char *path; > uint32_t key; > > weston_log("initializing drm backend\n"); > @@ -2188,30 +2242,12 @@ drm_compositor_create(struct wl_display *display, > goto err_udev; > } > > - e = udev_enumerate_new(ec->udev); > - udev_enumerate_add_match_subsystem(e, "drm"); > - udev_enumerate_add_match_sysname(e, "card[0-9]*"); > - > - udev_enumerate_scan_devices(e); > - drm_device = NULL; > - udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) { > - path = udev_list_entry_get_name(entry); > - device = udev_device_new_from_syspath(ec->udev, path); > - device_seat = > - udev_device_get_property_value(device, "ID_SEAT"); > - if (!device_seat) > - device_seat = default_seat; > - if (strcmp(device_seat, seat) == 0) { > - drm_device = device; > - break; > - } > - udev_device_unref(device); > - } > - > + drm_device = find_primary_gpu(ec, seat); > if (drm_device == NULL) { > weston_log("no drm device found\n"); > - goto err_udev_enum; > + goto err_tty; > } > + path = udev_device_get_syspath(drm_device); > > if (init_egl(ec, drm_device) < 0) { > weston_log("failed to initialize egl\n"); > @@ -2268,7 +2304,6 @@ drm_compositor_create(struct wl_display *display, > } > > udev_device_unref(drm_device); > - udev_enumerate_unref(e); > > return &ec->base; > > @@ -2289,8 +2324,7 @@ err_sprite: > destroy_sprites(ec); > err_udev_dev: > udev_device_unref(drm_device); > -err_udev_enum: > - udev_enumerate_unref(e); > +err_tty: > tty_destroy(ec->tty); > err_udev: > udev_unref(ec->udev); > -- > 1.8.0 > _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
