nvidia-prime/0000775000000000000000000000000012316303035010326 5ustar nvidia-prime/prime-offload0000775000000000000000000000562112301612440013001 0ustar #!/bin/sh # # Copyright 2013 Canonical Ltd. # # Author: Alberto Milone # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # LOG=/var/log/prime-offload.log prime_power=/proc/acpi/bbswitch prime_supported=/usr/bin/prime-supported # Remove any previous logs rm -f $LOG # Check hardware support here supported="`$prime_supported`" if [ -z "$supported" ]; then echo "Sorry but your hardware configuration is not supported" \ >> $LOG 2>&1 exit 0 fi # Only for NVIDIA's proprietary driver if ! lsmod | grep nvidia > /dev/null; then # Sorry the driver is not is loaded echo "Sorry the nvidia kernel module is not is loaded" \ >> $LOG 2>&1 exit 0 fi # Check the xrandr version randr_ver="$(xrandr -v)" client=$(echo "$randr_ver" | grep "program" | awk '{print $NF}' | cut -d. -f2) client_point=$(echo "$randr_ver" | grep "program" | awk '{print $NF}' | cut -d. -f3) server=$(echo "$randr_ver" | grep -i "server" | awk '{print $NF}' | cut -d. -f2) # There may not be a point version [ -z "$client_point" ] && client_point=0 if [ "$client" -ge 4 -a "$server" -ge 4 ]; then # client and server ver >= 1.4 use_randr_names=true elif [ "$client" -eq 3 -a "$client_point" -eq 5 \ -a "$server" -ge 4 ]; then # client ver 1.3.5 and server ver >= 1.4 use_randr_names=false else # client and server ver < 1.4 echo "Sorry we only support randr 1.4 or higher" \ >> $LOG 2>&1 exit 0 fi # Get the xrandr providers output="$(xrandr --listproviders)" if [ "$use_randr_names" = true ]; then # Use the providers' names src=$(echo "$output" | grep " Source" | \ head -n1 | awk '{print $NF}' | cut -d: -f2) sink=$(echo -e "$output" | grep " Sink" | \ head -n1 | awk '{print $NF}' | cut -d: -f2) else # Use the providers' ids src=$(echo "$output" | grep " Source" | \ head -n1 | cut -d: -f3 | cut -d" " -f2) sink=$(echo -e "$output" | grep " Sink" | \ head -n1 | cut -d: -f3 | cut -d" " -f2) fi # Pass provider or sink and source xrandr --setprovideroutputsource "$sink" "$src" # Make sure xrandr sees all the outputs xrandr --auto # Do not move up. Only now xrandr shows the outputs lvds=$(xrandr | grep -i -e "lvds" -e "edp" | head -n1 |cut -d " " -f 1) xrandr --output "$lvds" --off xrandr --output "$lvds" --auto nvidia-prime/prime-switch0000775000000000000000000000146712305373275012712 0ustar #!/bin/sh # # Copyright 2013 Canonical Ltd. # # Author: Alberto Milone # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Call the GPU manager /usr/bin/gpu-manager --log /var/log/gpu-manager.log exit 0 nvidia-prime/debian/0000755000000000000000000000000012316303172011550 5ustar nvidia-prime/debian/rules0000775000000000000000000000411612310352610012627 0ustar #!/usr/bin/make -f # -*- makefile -*- # # Copyright 2013 Canonical Ltd. # # Author: Alberto Milone # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 PKG_name = $(shell dh_listpackages) # Legacy configuration file for Lightdm # useful only in Precise PKG_lightdm_legacy_config_dir := /etc/lightdm PKG_lightdm_legacy_config_file := $(PKG_lightdm_legacy_config_dir)/lightdm.conf misc_dir := /usr/share/$(PKG_name) # New snippets for Lightdm in Ubuntu >= 13.04 PKG_lightdm_config_filename := 90-nvidia.conf PKG_lightdm_config_dir := /usr/share/lightdm/lightdm.conf.d PKG_lightdm_config_file := $(PKG_lightdm_config_dir)/$(PKG_lightdm_config_filename) XORG_CONF := /etc/X11/xorg.conf XORG_TEMPLATE := $(misc_dir)/xorg.template HOST_ARCH_MAIN ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) # If the host is i386 set OTHER_ARCH to x86_64 and vice versa HOST_ARCH_OTHER := $(shell (echo "$(HOST_ARCH_MAIN)" | grep i386 >/dev/null) && \ echo "$(HOST_ARCH_MAIN)" | sed s/i386/x86_64/ || \ echo "$(HOST_ARCH_MAIN)" | sed s/x86_64/i386/) %: dh $@ .PHONY: regen-from-templates regen-from-templates: for i in $(CURDIR)/debian/install \ $(CURDIR)/debian/dirs \ $(CURDIR)/debian/preinst \ $(CURDIR)/debian/postrm; do \ sed -e 's|#XORG_CONF#|$(XORG_CONF)|g' \ -e 's|#XORG_TEMPLATE#|$(XORG_TEMPLATE)|g' \ -e 's|#PKGNAME#|$(PKG_name)|g' \ -e "s|#LIGHTDM_LEGACY_CONF_FILE#|$(PKG_lightdm_legacy_config_file)|g" \ -e "s|#LIGHTDM_LEGACY_CONF_DIR#|$(PKG_lightdm_legacy_config_dir)|g" \ -e "s|#MISC_DIR#|$(misc_dir)|g" \ -e "s|#LIGHTDM_CONF_FILE#|$(PKG_lightdm_config_file)|g" \ -e "s|#LIGHTDM_CONF_DIR#|$(PKG_lightdm_config_dir)|g" \ -e "s|#LIGHTDM_CONF_FILENAME#|$(PKG_lightdm_config_filename)|g" \ -e "s|#HOST_ARCH_MAIN#|$(HOST_ARCH_MAIN)|g" \ -e "s|#HOST_ARCH_OTHER#|$(HOST_ARCH_OTHER)|g" \ $$i.in > $$i; \ done override_dh_auto_clean: for i in $(CURDIR)/debian/install \ $(CURDIR)/debian/dirs \ $(CURDIR)/debian/preinst \ $(CURDIR)/debian/postrm; do \ rm -f $$i; \ done override_dh_auto_install: regen-from-templates nvidia-prime/debian/compat0000664000000000000000000000000212140475356012761 0ustar 8 nvidia-prime/debian/install.in0000664000000000000000000000026112305373464013560 0ustar #LIGHTDM_CONF_FILENAME# #LIGHTDM_CONF_DIR# prime-quirks #MISC_DIR# prime-offload /sbin prime-switch /sbin get-quirk-options /sbin prime-select /usr/bin prime-supported /usr/bin nvidia-prime/debian/copyright0000664000000000000000000000177712152064773013532 0ustar Format: http://dep.debian.net/deps/dep5 Upstream-Name: nvidia-prime Source: git://github.com/tseliot/nvidia-prime.git Files: * Copyright: 2013 Canonical Ltd. License: GPL-3.0 Files: debian/* Copyright: 2013 Canonical Ltd. License: GPL-3.0 License: GPL-3.0 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". nvidia-prime/debian/preinst.in0000664000000000000000000000667412310361130013573 0ustar #!/bin/sh # preinst script for nvidia-prime # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `install' # * `install' # * `upgrade' # * `abort-upgrade' # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package lightdm_orig_conf=#LIGHTDM_LEGACY_CONF_FILE# default_display_manager_file=/etc/X11/default-display-manager add_hybrid_script () { if [ "`lsb_release -r -s`" = "12.04" ]; then # Precise does not support separate config files if [ -s "$lightdm_orig_conf" ]; then # Get the file lightdm_orig="$(cat $lightdm_orig_conf)" # See if a display setup script is already # in use if echo "$lightdm_orig" | \ grep "display-setup-script"; then echo "$lightdm_orig" | \ sed "s/.*display-setup-script.*/\ display-setup-script\=\/sbin\/prime-offload/g" \ > "$lightdm_orig_conf" else # Add a line after the pattern echo "$lightdm_orig" | \ sed '/.*user-session.*/ a\ display-setup-script\=\/sbin\/prime-offload' \ > "$lightdm_orig_conf" fi # Read the file again lightdm_orig="$(cat $lightdm_orig_conf)" # See if a display stopped script is already # in use if echo "$lightdm_orig" | \ grep "display-stopped-script"; then echo "$lightdm_orig" | \ sed "s/.*display-stopped-script.*/\ display-stopped-script\=\/sbin\/prime-switch/g" \ > "$lightdm_orig_conf" else # Add a line after the pattern echo "$lightdm_orig" | \ sed '/.*display-setup-script.*/ a\ display-stopped-script\=\/sbin\/prime-switch' \ > "$lightdm_orig_conf" fi fi else # Remove any configuration files that # nvidia-prime might have changed in previous # releases if [ -s "$lightdm_orig_conf" ]; then grep -e "display-setup-script=/sbin/prime-offload" \ -e "display-stopped-script=/sbin/prime-switch" \ -q $lightdm_orig_conf && rm -f $lightdm_orig_conf \ || true fi fi } case "$1" in install|upgrade) if [ -e "$default_display_manager_file" ]; then default_path="$(cat $default_display_manager_file)" display_manager="${default_path##*/}" # We currently support only lightdm if [ "$display_manager" = "lightdm" ]; then # Insert the display-*-script lines add_hybrid_script fi fi # Remove the lightdm config file from /etc if dpkg-maintscript-helper supports rm_conffile; then dpkg-maintscript-helper rm_conffile \ /etc/lightdm/lightdm.conf.d/90-nvidia.conf 0.6.1~ -- "$@" fi if [ ! -f /etc/prime-discrete ]; then echo "on" > /etc/prime-discrete fi ;; abort-upgrade) ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 nvidia-prime/debian/nvidia-prime.upstart0000664000000000000000000000207612305373272015575 0ustar # # Copyright 2013 Canonical Ltd. # # Author: Alberto Milone # # NVIDIA PRIME - Power Saving Mode # # On system shutdown we remove bbswitch and re-enable # the NVIDIA card. # description "NVIDIA PRIME Power Saving Mode" author "Alberto Milone " start on starting lightdm stop on runlevel [016] emits nvidia-off emits bbswitch-ready script LOG=/var/log/nvidia-prime-upstart.log prime_supported=/usr/bin/prime-supported # Remove any previous logs rm -f $LOG # Check hardware support here supported="`$prime_supported`" if [ -z "$supported" ]; then echo "Sorry but your hardware configuration is not supported" \ >> $LOG 2>&1 # We're probably dealing with a system with a single # NVIDIA card here, so we make sure to start nvidia-persistence # with some delay /usr/bin/start-nvidia-persistenced exit 0 fi end script pre-stop script if lsmod | grep bbswitch > /dev/null; then /sbin/rmmod bbswitch fi end script nvidia-prime/debian/changelog0000664000000000000000000001736512316303164013441 0ustar nvidia-prime (0.6.2) trusty; urgency=medium * prime-supported: - Check /var/lib/ubuntu-drivers-common/requires_offloading to know if we need to offload rendering. There's no need to do hardware detection again when the gpu-manager already does all the work. -- Alberto Milone Mon, 31 Mar 2014 17:13:37 +0200 nvidia-prime (0.6.1) trusty; urgency=medium * debian/preinst.in, debian/rules: - Move the lightdm configuration file from /etc to /usr/share. -- Alberto Milone Thu, 13 Mar 2014 17:13:50 +0100 nvidia-prime (0.6) trusty; urgency=low * debian/control: - Breaks: ubuntu-drivers-common (<< 1:0.2.89). * Add support for the new ubuntu-drivers-common. The gpu-manager will take care of most of the work. We only need to tell lightdm that we want to offload rendering, and to run the gpu-manager on log out. -- Alberto Milone Thu, 06 Mar 2014 09:19:12 +0100 nvidia-prime (0.5.7) trusty; urgency=low * debian/preinst.in: - Do not remove the lightdm configuration file. -- Alberto Milone Fri, 21 Feb 2014 14:49:59 +0100 nvidia-prime (0.5.6) trusty; urgency=low [ Daniel Dadap ] * prime-xconfig: - Format the BusID string correctly (LP: #1282796). The BusID string created by prime-xconfig had several problems: 1) It was missing the bus type "PCI", as recommended by xorg.conf(5). 2) Values were written in hexadecimal, as reported by lspci, instead of decimal, as expected by the server. (See the comment at the top of xf86ParsePciBusString().) 3) The PCI domain was not specified. Giving the BusID string in the wrong format could cause the X server to fail to parse the BusID, or to parse numbers in the wrong base. On systems with more than one PCI domain, `lspci -n` output would include the domain number, which is omitted by default on systems with only one PCI domain. nv_get_id() expects the bus number to be the first field, which would not be correct when `lspci -n` reports the domain, as it does on systems with multiple domains. Fix these issues by always reporting the domain with `lspci -Dn` and using it in the BusID string, prepending "PCI:" to the BusID string, and printing all numeric values in decimal. -- Alberto Milone Fri, 21 Feb 2014 09:50:34 +0100 nvidia-prime (0.5.5) trusty; urgency=low * debian/rules: - Fix path to lightdm configuration files. -- Alberto Milone Fri, 31 Jan 2014 16:12:44 +0100 nvidia-prime (0.5.4) trusty; urgency=low * Do not touch lightdm.conf any more on anything newer than Precise. 90-nvidia.conf now contains only the relevant settings for PRIME (LP: #1267442). * Also remove any previous lightdm.conf that nvidia-prime might have messed up. * Major packaging clean-up. The variable in debian/rules and in templates have clearer names now. * Clean up the old 90-nvidia.conf that we used to ship in /etc. -- Alberto Milone Tue, 28 Jan 2014 17:30:43 +0100 nvidia-prime (0.5.3) trusty; urgency=low * debian/postrm.in, debian/rules: - Avoid calling dpkg-architecture (LP: #1264611). * prime-xconfig: - Properly format hexadecimal parameters (LP: #1252667). -- Alberto Milone Fri, 10 Jan 2014 14:41:22 +0100 nvidia-prime (0.5.2) trusty; urgency=low * debian/control: - Add an alternative dependency on gdm and kdm so that gdm or kdm users are not forced to install lightdm now that nvidia depends on nvidia-prime. This fixes only the single graphics card use case (hybrid graphics won't still work without lightdm) but it's a step in the right direction (LP: #1262068). * debian/preinst.in: - Set the lightdm configuration bits only if lightdm is the default display manager. -- Alberto Milone Fri, 20 Dec 2013 15:43:58 +0100 nvidia-prime (0.5.1) trusty; urgency=low * debian/nvidia-prime.upstart, prime-switch: - Send events to start and to stop the nvidia-persistenced upstart job. -- Alberto Milone Tue, 17 Dec 2013 10:26:25 +0100 nvidia-prime (0.5) trusty; urgency=low * debian/control: - Depend on bbswitch-dkms and upstart. - Depend on lightdm (>= 1.9.1). - Build only for i386 and amd64. * debian/install.in: - Install the new components. * debian/nvidia-prime.upstart: - Make sure that NVIDIA is always enabled on shutdown. This will avoid issues with the BIOS. - Make sure that bbswitch does not disable nvidia when loading. - Set up xorg.conf on boot. * debian/preinst.in: - Create a display-stopped-script entry in lightdm.conf. - Create /etc/lightdm/hybrid_default. * debian/postinst.in: - Remove it. * debian/postrm.in: - Remove /etc/lightdm/hybrid_default on package removal. - Remove the display-stopped-script entry from lightdm.conf. - Restore the non-prime related alternative on removal. * New upstream release: - Improved hardware detection. The package won't change anything if the hardware configuration is not supported. We only support laptops with NVIDIA optimus hardware and nvidia driver >= 319 (LP: #1249067). - More robust system to deal with xorg.conf. Broken xorg.conf files will be automatically restored to a configuration that works with hybrid graphics. Whether on boot or on log out, we always try to make sure that the system is configured correctly. - Added prime-select switcher to switch between the integrated and the discrete GPU. This allows users to disable the discrete GPU to save power. Users' settings are now saved and applied on log out and on boot. - Added a quirk system to pass custom options to the bbswitch module (see /etc/prime-quirks). -- Alberto Milone Wed, 04 Dec 2013 16:23:32 +0100 nvidia-prime (0.4.2) trusty; urgency=low * debian/postinst.in: fix issue with printf - Apparently the printf command treats string values with leading zeros as octal. Work around this by removing any leading zeros (LP: #1219650). -- Alberto Milone Wed, 23 Oct 2013 15:45:24 +0200 nvidia-prime (0.4.1) trusty; urgency=low * debian/preinst.in: - Remove leftover in the test condition. This was causing the lightdm.conf file to be rewritten every time. This is a serious problem on the different Ubuntu flavours (LP: #1224098). -- Alberto Milone Wed, 23 Oct 2013 13:03:55 +0200 nvidia-prime (0.4) saucy; urgency=low * debian/postinst.in, hybrid-power: - Make sure to support more pci device classes as per the pci.ids file (LP: #1207626). -- Alberto Milone Thu, 08 Aug 2013 11:27:27 +0200 nvidia-prime (0.3) saucy; urgency=low * debian/postinst.in: - Do not touch the lightdm.conf (LP: #1199342). * debian/preinst.in: - Create a lightdm.conf if none can be found. -- Alberto Milone Wed, 24 Jul 2013 10:20:06 +0200 nvidia-prime (0.2) saucy; urgency=low * debian/control: - Conflict/replace/provide the hybrid-graphics virtual package. * Make sure to start X instead of XMir or hybrid graphics won't work, at least for now. -- Alberto Milone Wed, 03 Jul 2013 11:42:17 +0200 nvidia-prime (0.1) saucy; urgency=low * Initial Release. -- Alberto Milone Fri, 31 May 2013 14:10:46 +0200 nvidia-prime/debian/postrm.in0000664000000000000000000001060312305370320013423 0ustar #!/bin/sh # postrm script for nvidia-prime # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `purge' # * `upgrade' # * `failed-upgrade' # * `abort-install' # * `abort-install' # * `abort-upgrade' # * `disappear' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package xorg_conf="#XORG_CONF#" now=$(date +"%m%d%Y") lightdm_orig_conf=#LIGHTDM_LEGACY_CONF_FILE# host_arch_main=#HOST_ARCH_MAIN# host_arch_other=#HOST_ARCH_OTHER# remove_hybrid_script () { # Precise only! if [ -s "$lightdm_orig_conf" ]; then # Get the file lightdm_orig="$(cat $lightdm_orig_conf)" echo "$lightdm_orig" | \ sed "/.*display-setup-script.*/d" \ > "$lightdm_orig_conf" lightdm_orig="$(cat $lightdm_orig_conf)" echo "$lightdm_orig" | \ sed "/.*display-stopped-script.*/d" \ > "$lightdm_orig_conf" fi } get_current_alternative() { master_link="$1" value="" alternatives="$(update-alternatives --query "$master_link" 2>/dev/null || true)" if [ -n "$alternatives" ]; then #status=$(echo "$alternatives" | grep "Status:" | sed "s/Status: //g") value="$(echo "$alternatives" | grep "Value:" | sed "s/Value: //g")" fi echo "$value" } set_alternative() { master_link="$1" path="$2" update-alternatives --set "$master_link" "$path" || true } case "$1" in purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) # Remove the xorg.conf if [ -f $xorg_conf ]; then mv $xorg_conf $xorg_conf.$now fi if [ ! "$1" = "upgrade" ]; then if [ "$os_release" = "precise" ]; then # Remove the display-setup-script line remove_hybrid_script fi # Remove the settings rm -f /etc/prime-discrete # Restore the alternatives to a non prime # configuration, if possible os_release="$(lsb_release -cs)" main_arch=""$host_arch_main"_gl_conf" other_arch=""$host_arch_other"_gl_conf" main_alternative="$(get_current_alternative "$main_arch")" other_alternative="$(get_current_alternative "$other_arch")" if echo "$main_alternative" | grep "prime"; then if [ "$os_release" = "precise" ]; then # In Precise multiple drivers can be installed at the # same time, so we simply switch back to the non-prime # alternative provided by the same driver package fallback="$(echo "$main_alternative" | sed "s/-prime//g")" set_alternative "$main_arch" "$fallback" else # Drivers cannot be installed all at the # same time, therefore it is recommended # that we set the alternative back to # automatic mode. update-alternatives --auto "$main_arch" || true fi fi if echo "$other_alternative" | grep "prime"; then if [ "$os_release" = "precise" ]; then # In Precise multiple drivers can be installed at the # same time, so we simply switch back to the non-prime # alternative provided by the same driver package fallback="$(echo "$other_alternative" | sed "s/-prime//g")" set_alternative "$other_arch" "$fallback" else # Drivers cannot be installed all at the # same time, therefore it is recommended # that we set the alternative back to # automatic mode. update-alternatives --auto "$other_arch" || true fi fi LDCONFIG_NOTRIGGER=y ldconfig fi ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 nvidia-prime/debian/docs0000664000000000000000000000000012140475356012424 0ustar nvidia-prime/debian/control0000664000000000000000000000126612306027530013162 0ustar Source: nvidia-prime Section: admin Priority: optional Maintainer: Alberto Milone Build-Depends: debhelper (>= 8.0.0) Standards-Version: 3.9.2 Vcs-Git: git://github.com/tseliot/nvidia-prime.git Vcs-Browser: http://github.com/tseliot/nvidia-prime Package: nvidia-prime Architecture: i386 amd64 Depends: lightdm (>= 1.9.1) | gdm | kdm, upstart, bbswitch-dkms, pciutils, lsb-release, ${shlibs:Depends}, ${misc:Depends} Conflicts: hybrid-graphics Replaces: hybrid-graphics Provides: hybrid-graphics Breaks: ubuntu-drivers-common (<< 1:0.2.89) Description: Tools to enable NVIDIA's Prime This is a set of tools which will enable NVIDIA's Prime on MUXless systems. nvidia-prime/debian/dirs.in0000664000000000000000000000010112305370320013030 0ustar /etc/X11 #MISC_DIR# #LIGHTDM_LEGACY_CONF_DIR# #LIGHTDM_CONF_DIR# nvidia-prime/debian/source/0000755000000000000000000000000012140475356013061 5ustar nvidia-prime/debian/source/format0000664000000000000000000000001512140475356014272 0ustar 3.0 (native) nvidia-prime/get-quirk-options0000775000000000000000000000272712301612440013662 0ustar #!/bin/sh # # Copyright 2013 Canonical Ltd. # # Author: Alberto Milone # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # LOG="/var/log/prime-quirks.log" quirks="/usr/share/nvidia-prime/prime-quirks" dmi_prod_ver_path="/sys/class/dmi/id/product_version" additional_opts="" if [ -s "$quirks" ] && [ -s "$dmi_prod_ver_path" ]; then dmi_prod_ver="`cat "$dmi_prod_ver_path"`" while read line; do if [ -n "$line" ] && [ -n "`echo "$line" | grep -v "#"`" ]; then product="`echo "$line" | cut -d '"' -f 2`" if [ "$dmi_prod_ver" = "$product" ]; then options="`echo "$line" | cut -d '"' -f 4`" echo "Applying quirk for $product\n$options" \ > $LOG 2>&1 additional_opts="$options" break fi fi done < "$quirks" fi echo "$additional_opts" nvidia-prime/90-nvidia.conf0000664000000000000000000000024412305370320012674 0ustar [SeatDefaults] # Force using traditional X type=xlocal # Scripts to handle PRIME display-setup-script=/sbin/prime-offload display-stopped-script=/sbin/prime-switch nvidia-prime/prime-quirks0000664000000000000000000000031612301612440012676 0ustar # Quirks file for nvidia-prime # # You can add quirks using the following format: # # "dmi product version" "bbswitch options" # "ThinkPad T410" "skip_optimus_dsm=1" "ThinkPad T410s" "skip_optimus_dsm=1" nvidia-prime/prime-supported0000775000000000000000000000223612316301523013416 0ustar #!/bin/sh # # Copyright 2013 Canonical Ltd. # # Author: Alberto Milone # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # LOG=/var/log/prime-supported.log if [ -n "$1" ]; then LOG="$1" fi # Remove any previous logs # as long as the log is an actual # file. In some cases we may pass # it /dev/stdout which is a link if [ -f $LOG ]; then rm -f $LOG fi if [ -e "/var/lib/ubuntu-drivers-common/requires_offloading" ]; then echo "Requires offloading" >> $LOG 2>&1 echo "yes" else echo "No offloading required. Abort" >> $LOG 2>&1 exit 0 fi nvidia-prime/prime-select0000775000000000000000000003313512301612440012647 0ustar #!/usr/bin/python # # prime-select # # Copyright 2013 Canonical Ltd. # Author: Alberto Milone # # Script to switch between NVIDIA and Intel graphics driver libraries. # # Usage: # prime-select nvidia|intel|query # nvidia: switches to NVIDIA's version of libGL.so # intel: switches to the open-source version of libGL.so # query: checks which version is currently active and writes # "nvidia", "intel" or "unknown" to the standard output # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. import os import sys import re import subprocess from subprocess import Popen, PIPE, CalledProcessError class Alternatives: def __init__(self, master_link): self._open_drivers_alternative = 'mesa/ld.so.conf' self._open_egl_drivers_alternative = 'mesa-egl/ld.so.conf' self._command = '/usr/bin/update-alternatives' self._master_link = master_link # Make sure that the PATH environment variable is set if not os.environ.get('PATH'): os.environ['PATH'] = '/sbin:/usr/sbin:/bin:/usr/bin' def list_alternatives(self): '''Get the list of alternatives for the master link''' dev_null = open('/dev/null', 'w') alternatives = [] p1 = Popen([self._command, '--list', self._master_link], stdout=PIPE, stderr=dev_null) p = p1.communicate()[0] dev_null.close() c = p.split('\n') for line in c: line.strip() and alternatives.append(line.strip()) return alternatives def get_current_alternative(self, check_status=False): '''Get the alternative in use If check_status is True, then only the status will be reported (i.e. either "manual" or "auto") ''' dev_null = open('/dev/null', 'w') current_alternative = None p1 = Popen([self._command, '--query', self._master_link], stdout=PIPE, stderr=dev_null) p = p1.communicate()[0] dev_null.close() c = p.split('\n') if check_status: pattern = 'Status:' else: pattern = 'Value:' for line in c: if line.strip().startswith(pattern): return line.replace(pattern, '').strip() return None def get_alternative_by_name(self, name, ignore_pattern=None): '''Get the alternative link by providing the driver name ignore_pattern allows ignoring a substring in the name''' if ignore_pattern: name = name.replace(ignore_pattern, '') alternatives = self.list_alternatives() for alternative in alternatives: if alternative.split('/')[-2] == name: return alternative return None def get_open_drivers_alternative(self): '''Get the alternative link for open drivers''' return self.get_alternative_by_name(self._open_drivers_alternative) def get_open_egl_drivers_alternative(self): '''Get the alternative link for open EGL/GLES drivers''' return self.get_alternative_by_name(self._open_egl_drivers_alternative) def set_alternative(self, path): '''Tries to set an alternative and returns the boolean exit status''' try: subprocess.check_call([self._command, '--set', self._master_link, path]) self.ldconfig() except CalledProcessError: return False return True def ldconfig(self): '''Call ldconfig''' try: subprocess.check_call(['/sbin/ldconfig']) except CalledProcessError: return False return True class Switcher(object): def __init__(self): self._power_profile_path = '/etc/prime-discrete' self._supported_architectures = {'i386': 'i386', 'amd64': 'x86_64'} main_arch = self._get_architecture() other_arch = self._supported_architectures.values()[ int(not self._supported_architectures .values().index(main_arch))] main_alternative_name = self._get_alternative_name_from_arch(main_arch) other_alternative_name = self._get_alternative_name_from_arch(other_arch) # We have 2 alternatives, one for each architecture self._gl_switcher = Alternatives(main_alternative_name) self._gl_switcher_other = Alternatives(other_alternative_name) def _get_architecture(self): dev_null = open('/dev/null', 'w') p1 = Popen(['dpkg', '--print-architecture'], stdout=PIPE, stderr=dev_null) p = p1.communicate()[0] dev_null.close() architecture = p.strip() return self._supported_architectures.get(architecture) def _get_alternative_name_from_arch(self, architecture): alternative = '%s-linux-gnu_gl_conf' % architecture return alternative def _simplify_x_alternative_name(self, alternative): return alternative.split('/')[-1] def _simplify_gl_alternative_name(self, alternative): return alternative.split('/')[-2] def _get_gl_alternatives_list(self): raw_alternatives = self._gl_switcher.list_alternatives() return [ self._simplify_gl_alternative_name(x) for x in raw_alternatives ] def _update_initramfs(self): subprocess.call(['update-initramfs', '-u']) # This may not be necessary subprocess.call(['update-initramfs', '-u', '-k', os.uname()[2]]) def _get_current_alternative(self): # This is a list as the 2nd item belongs to another architecture alternatives = [None, None] raw_gl_alternative = self._gl_switcher.get_current_alternative() raw_gl_alternative_other = self._gl_switcher_other.get_current_alternative() if (raw_gl_alternative != None): alternatives[0] = self._simplify_gl_alternative_name(raw_gl_alternative) if (raw_gl_alternative_other != None): alternatives[1] = self._simplify_gl_alternative_name(raw_gl_alternative_other) return alternatives def _get_current_alternative_status(self): '''Get the current status i.e. either "auto" or "manual"''' # This is a list as the 2nd item belongs to another architecture alternatives = [None, None] raw_gl_alternative = self._gl_switcher.get_current_alternative(True) raw_gl_alternative_other = self._gl_switcher_other.get_current_alternative(True) if (raw_gl_alternative != None): alternatives[0] = raw_gl_alternative if (raw_gl_alternative_other != None): alternatives[1] = raw_gl_alternative_other return alternatives def enable_alternative(self, alternative): # Make sure that the alternative exists gl_alternative = self._gl_switcher.get_alternative_by_name(alternative) gl_alternative_other = self._gl_switcher_other.get_alternative_by_name(alternative) # See if they are null # Abort if gl_alternative is null if gl_alternative and gl_alternative_other: success = (self._gl_switcher.set_alternative(gl_alternative) and self._gl_switcher_other.set_alternative(gl_alternative_other)) return success else: sys.stderr.write("Error: no alternative can be found for %s\n" % alternative) return False def print_current_alternative(self): alternatives = self._get_current_alternative() try: alternative = str(alternatives[0]) alternative_other = str(alternatives[1]) except IndexError: # No alternative exists return False if (alternative == alternative_other and 'nvidia' in alternative): if 'prime' in alternative: sys.stdout.write('intel\n') else: sys.stdout.write('nvidia\n') else: sys.stdout.write('unknown\n') return True def _write_profile(self, profile): if profile == 'intel': nvidia_power = 'off' elif profile == 'nvidia': nvidia_power = 'on' else: return False # Write the settings to the file settings = open(self._power_profile_path, 'w') settings.write('%s\n' % nvidia_power) settings.close() def enable_profile(self, profile): current_driver = '' current_profile = '' alternatives = self._get_current_alternative() try: alternative = str(alternatives[0]) alternative_other = str(alternatives[1]) except IndexError: # No alternative exists sys.stderr.write('Error: the required alternatives do not exist\n') return False # The alternatives we are looking for are both provided by # an nvidia package if (alternative == alternative_other and 'nvidia' in alternative): # The driver in use current_driver = alternative # The profile in use if 'prime' in alternative: current_profile = 'intel' else: current_profile = 'nvidia' # Check that the alternative for the intel profile # exists. If it doesn't, then the driver does not # support power management with PRIME alt_driver = '%s-prime' % current_driver if (not self._gl_switcher.get_alternative_by_name(alt_driver) or not self._gl_switcher_other.get_alternative_by_name(alt_driver)): sys.stderr.write('Error: %s does not support PRIME power management\n') return False # Are alternatives in "auto" or in "manual" mode? status = self._get_current_alternative_status() # No need to do anything if we're already using the desired # profile, provided that alternatives are not in "auto" mode if profile == current_profile and 'auto' not in status: sys.stdout.write('Info: the %s profile is already in use\n' % (profile)) return True elif (alternative != alternative_other and 'nvidia' in alternative): # Something's wrong here # e.g. nvidia-319 on x86_64 and mesa on i386 sys.stdout.write('Info: the alternatives do not match\n') # The first alternative shows the driver in use current_driver = alternative if 'prime' not in alternative: # Check that the alternative for the intel profile # exists. If it doesn't, then the driver does not # support power management with PRIME alt_driver = '%s-prime' % current_driver if (not self._gl_switcher.get_alternative_by_name(alt_driver) or not self._gl_switcher_other.get_alternative_by_name(alt_driver)): sys.stderr.write('Error: %s does not support PRIME power management\n') return False else: sys.stderr.write('Error: alternatives are not set up properly\n') return False # Enable the desired alternative if profile == 'intel': target_driver = '%s-prime' % current_driver else: target_driver = current_driver.replace('-prime', '') if self.enable_alternative(target_driver): # Write the settings to the config file self._write_profile(profile) return True else: return False def check_root(): if not os.geteuid() == 0: sys.stderr.write("This operation requires root privileges\n") exit(1) def handle_alternatives_error(mode): sys.stderr.write('Error: %s mode can\'t be enabled\n' % mode) exit(1) def handle_query_error(): sys.stderr.write("Error: no alternative can be found\n") exit(1) def usage(): sys.stderr.write("Usage: %s nvidia|intel|query\n" % (sys.argv[0])) if __name__ == '__main__': try: arg = sys.argv[1] except IndexError: arg = None if len(sys.argv[1:]) != 1: usage() exit(1) switcher = Switcher() if arg == 'intel' or arg == 'nvidia': check_root() if not switcher.enable_profile(arg): handle_alternatives_error(arg) elif arg == 'query': if not switcher.print_current_alternative(): handle_query_error() else: usage() sys.exit(1) exit(0)