[ubuntu-x] Hybrid graphics detection

Bryce Harrington bryce at canonical.com
Mon Oct 31 18:54:17 UTC 2011


Thanks Evan

On Mon, Oct 31, 2011 at 11:36:39AM -0700, Evan Broder wrote:
> At the hybrid graphics session today, we discussed how we could detect
> which GPU was actively being used in a hybrid graphics configuration.
> I have some code that I've been using to do this, using libpciaccess.
> 
> It's based on the code that X itself uses to pick which drivers to
> load at startup, so it likely suffers from some of the issues we
> discussed in the session. But it does seem to work for nVidia Optimus,
> which is the only hybrid graphics system I have access to.
> 
> I'm currently using the following Upstart job when either
> nvidia-current or fglrx are installed:
> 
>  start on starting gdm
> 
>  task
>  script
>      if [ "$(hybrid-detect)" = "integrated" ]; then
>          update-alternatives --set gl_conf /usr/lib/mesa/ld.so.conf
>          ldconfig
>      fi
>  end script
> 
> Both of these are a bit rough around the edges, and would definitely
> need some tuning before being adapted by Ubuntu in general.
> 
> - Evan

> /* hybrid-detect:
>  *
>  * Detect which GPU in a hybrid graphics configuration should be
>  * used
>  *
>  * Based on code from ./hw/xfree86/common/xf86pciBus.c in xorg-server
>  *
>  * Build with `gcc -o hybrid-detect hybrid-detect.c $(pkg-config --cflags --libs pciaccess)`
>  */
> 
> #include <stdio.h>
> #include <pciaccess.h>
> 
> #define PCI_CLASS_PREHISTORIC           0x00
> 
> #define PCI_CLASS_DISPLAY               0x03
> 
> #define PCI_CLASS_MULTIMEDIA            0x04
> #define PCI_SUBCLASS_MULTIMEDIA_VIDEO   0x00
> 
> #define PCI_CLASS_PROCESSOR             0x0b
> #define PCI_SUBCLASS_PROCESSOR_COPROC   0x40
> 
> #define PCIINFOCLASSES(c)                                               \
>     ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16))             \
>       || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16))              \
>       || ((((c) & 0x00ffff00)                                           \
>            == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) \
>       || ((((c) & 0x00ffff00)                                           \
>            == ((PCI_CLASS_PROCESSOR << 16) | (PCI_SUBCLASS_PROCESSOR_COPROC << 8)))) )
> 
> static struct pci_slot_match match = {
>     PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0
> };
> 
> int main(int argc, char *argv[]) {
>     pci_system_init();
> 
>     struct pci_device_iterator *iter = pci_slot_match_iterator_create(&match);
>     if (!iter)
>         return 1;
> 
>     struct pci_device *info;
>     while ((info = pci_device_next(iter)) != NULL) {
>         if (PCIINFOCLASSES(info->device_class) &&
>             pci_device_is_boot_vga(info)) {
>             if (info->vendor_id == 0x8086)
>                 printf("integrated\n");
>             else
>                 printf("discrete\n");
>             break;
>         }
>     }
> 
>     pci_iterator_destroy(iter);
>     return 0;
> }

> -- 
> Ubuntu-x mailing list
> Ubuntu-x at lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/ubuntu-x




More information about the Ubuntu-x mailing list