[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