this tutorial is outdated,
better check
or
old Post:
-
first of all, sorry for bad english
-
delete all gpu drivers with mhwd (mhwd -li list installed drivers)
-
get bus ids of gpus with lspci | grep VGA
Nvidia:
- install video-nvidia with mhwd
- edit (or create) /etc/X11/mhwd.d/nvidia.conf (busid need correct format, 01:00.0 -> 1:0:0):
Section "Module"
Load "modesetting"
EndSection
Section "Device"
Identifier "nvidia"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Geforce GT630M"
BusID "PCI:1:0:0" # use correct busid for nvidia gpu
Option "Coolbits" "8" # show powermizer panel in nvidia settings, value depends on graphic card
EndSection
Section "Monitor" # eliminate "ghost" output, not needed
Identifier "VGA-1-1"
Option "Ignore" "1"
EndSection
Section "Monitor" # eliminate "ghost" output, not needed
Identifier "VGA-0"
Option "Ignore" "1"
EndSection
- create file /etc/X11/mhwd.d/prime-offload.sh:
#!/bin/sh
#xrandr --dpi 96 # you can set dpi here (also in nvidia.conf file)
xrandr --setprovideroutputsource modesetting NVIDIA-0
xrandr --auto
exec nvidia-settings --load-config-only
- add to .xinitrc or /etc/X11/xinit/xinitrc (or see edit below) if you dont use display manager:
[ -f /etc/X11/mhwd.d/prime-offload.sh ] && . /etc/X11/mhwd.d/prime-offload.sh &
EDIT 09.09.2017:
or
- you can also create a new script in /etc/X11/xinitrc.d instead, this is possible the most convenient approach,
e.g.:
/etc/X11/xinit/xinitrc.d/99-prime-offload.sh:
#!/bin/sh
[ -f /etc/X11/mhwd.d/prime-offload.sh ] && . /etc/X11/mhwd.d/prime-offload.sh &
//EDIT
- if you use display manager:
sddm:
edit /usr/share/sddm/scripts/Xsetup:
[ -f /etc/X11/mhwd.d/prime-offload.sh ] && . /etc/X11/mhwd.d/prime-offload.sh
lightdm:
- create /etc/lightdm/display_setup.sh
#!/bin/sh
[ -f /etc/X11/mhwd.d/prime-offload.sh ] && . /etc/X11/mhwd.d/prime-offload.sh
- make script executable:
chmod +x /etc/lightdm/display_setup.sh
- Now configure lightdm to run the script by editing the [Seat:*] section in /etc/lightdm/lightdm.conf:
/etc/lightdm/lightdm.conf:
[Seat:*]
display-setup-script=/etc/lightdm/display_setup.sh
(taken from arch webpage https://wiki.archlinux.org/index.php/NVIDIA_Optimus, never used lightdm myself)
- edit/create /etc/modules-load.d/mhwd-gpu.conf:
nvidia
nvidia-drm
nvidia-uvm
- edit/create /etc/modprobe.d/mhwd-gpu.conf:
blacklist nouveau
blacklist ttm
options nvidia-drm modeset=1
(last one is for vsync, not necessarily needed)
- reboot pc, nvidia driver should work now, if not check /var/log/Xorg.0.log
Intel: (here you can use either intel driver or modesetting driver, modesetting driver should work without anything installed
- install video-intel with mhwd (shouldn't be necessary if you use modesetting, but never tested it without)
- edit /etc/X11/mhwd.d/intel.conf (busid need correct format) :
INTEL DRIVER:
Section "OutputClass" # needed if nvidia module loaded
Identifier "intel"
ModulePath "/usr/lib/xorg/modules/extensions"
EndSection
Section "Device"
Identifier "intel"
Driver "intel"
BusID "PCI:0:2:0" # correct busid
Option "DRI" "true"
Option "TearFree" "true" # not an option for modesetting
EndSection
Section "DRI"
Group "video"
Mode 0666
EndSection
MODESETTING DRIVER:
Section "OutputClass" # needed if nvidia module loaded
Identifier "intel"
ModulePath "/usr/lib/xorg/modules/extensions"
EndSection
Section "Device"
Identifier "intel"
Driver "modesetting"
BusID "PCI:0:2:0" # correct busid
EndSection
-
edit /etc/modules-load.d/mhwd-gpu.conf (not necessary):
either:
leave empty -
or:
add nvidia modules -
or:
add nouveau (if you have xf86-video-nouveau installed.) -
edit /etc/modprobe.d/mhwd-gpu.conf:
either:
blacklist nouveau
blacklist ttm
or: (if you want to use nouveau)
blacklist nvidia
blacklist nvidia-modeset
blacklist nvidia-uvm
blacklist nvidia-drm
- for switching without reboot, load nvidia modules with intel (or keep file empty)
- outputclass section: I use it this way in the intel config because if nvidia module is loaded and you start x without modulepath libglx cant be found (for me)
Switching:
- use script like this:
#!/usr/bin/python3
import os,shutil,subprocess,re
import argparse
import json
# default config
config = {
"modules_load_file": "/etc/modules-load.d/mhwd-gpu.conf",
"modules_modprobe_file": "/etc/modprobe.d/mhwd-gpu.conf",
"mhwd_symlink_target": "/etc/X11/xorg.conf.d/90-mhwd.conf",
"prime_offload_script": "/etc/X11/mhwd.d/prime-offload.sh",
"driver": {
"intel": {
"xorg_file": "/etc/X11/mhwd.d/intel.conf",
"xrandr_offload": False,
"modules_load": [],
"modules_blacklist": ["nouveau","ttm"],
"modules_options": []
},
"nvidia": {
"xorg_file": "/etc/X11/mhwd.d/nvidia.conf",
"xrandr_offload": True,
"modules_load": ["nvidia","nvidia-drm","nvidia-uvm"],
"modules_blacklist": ["nouveau","ttm"],
"modules_options": ["nvidia-drm modeset=1"]
}
}
}
def create_parser():
parser = argparse.ArgumentParser()
parser.add_argument(
"-d", "--driver",
#required=True,
#choices=config["driver"].keys(),
help="Switch to this driver (e.g. intel or nvidia)"
)
parser.add_argument(
"-c", "--config",
help="Path to config file (only needed if you want to use non default settings)"
)
parser.add_argument(
"-s", "--show-config",
nargs='?',
const=True,
metavar="Filename",
help="Dumps default config to stdout or filename if specified (only useful if you want to mess around with default settings and use with -c switch afterwards)"
)
return(parser.parse_args())
class Info:
def returnCurDrivers(self):
from collections import OrderedDict
sh = 'lspci -D|grep VGA'
cmd = subprocess.getstatusoutput(sh)
if cmd[0] == 0:
gpus = OrderedDict() # mabey use just normal dict instead
gpu = cmd[1].split("\n")
for i,v in enumerate(gpu):
gpus[i] = self.splitlspci(v)
for k,v in gpus.items():
f = open("/sys/bus/pci/devices/"+v[0]+"/uevent")
v.append(f.read())
return(gpus)
else: # subprocess.getstatusoutput failed
print("Error %s\nErrorcode %i " %(sh,cmd[0]))
def splitlspci(self,cmd):
pci = cmd.split(" ")[0]
se = pci+'.*controller:'
card = re.split(se,cmd)[1].lstrip()
return([pci,card])
class Util:
def changeModules(self,load,blacklist,options):
# modules to load
f1 = open(config["modules_load_file"],"w") # start with empty file
if len(load) > 0:
for i in load:
f1.write(i+"\n")
print("Load: %s" %i)
f1.close()
# modules to blacklist
f2 = open(config["modules_modprobe_file"],"w") # start with empty file
if len(blacklist) > 0:
for j in blacklist:
f2.write("blacklist "+j+"\n")
print("Blacklist: %s" %j)
# modules options
if len(options) > 0:
for k in options:
f2.write("options "+k+"\n")
print("Option: options %s" %k)
f2.close()
#
# switchDriver function:
# par1=conf to symlink
# par2=target file symlink points to (default /etc/X11/xorg.conf.d/90-mhwd.conf)
# par3=prime-offload script disable or enable
# par4=modules to load (list)
# par5=modules to blacklist (list)
# par6=modules options (list)
#
def switchDriver(self,src, trg=config["mhwd_symlink_target"], *, prioff, mload, mblacklist, moptions):
try:
os.unlink(trg)
os.symlink(src,trg)
print("Symlink %s -> %s" %(src,trg))
if prioff == False:
fe = os.path.isfile(config["prime_offload_script"])
if fe is True:
os.rename(config["prime_offload_script"],config["prime_offload_script"]+"-disabled")
elif prioff:
fe = os.path.isfile(config["prime_offload_script"]+"-disabled")
if fe is True:
os.rename(config["prime_offload_script"]+"-disabled",config["prime_offload_script"])
else:
raise ValueError('%s\nUse either true or false not:\n%s' %(config["prime_offload_script"],str(prioff)))
self.changeModules(mload,mblacklist,moptions)
return True
except Exception as e:
return(str(e))
if __name__ == "__main__":
args = create_parser()
if args.show_config is True:
print(json.dumps(config, indent=4, separators=(',', ': ')))
exit(0)
elif isinstance(args.show_config,str): # filename specified
print("dump config to file %s" %args.show_config)
with open(args.show_config,"w") as f:
f.write(json.dumps(config, indent=4, separators=(',', ': ')))
exit(0)
if args.config is not None:
with open(args.config,"r") as f:
config = json.loads(f.read())
if args.driver is None: print("No driver specified"); exit(1);
if args.driver is not None:
drivers = list(config["driver"].keys())
if os.getuid() != 0:
# not root user
print("Please execute as root")
exit(2)
#elif args.driver in config["driver"].keys():
elif args.driver in drivers:
res = Util().switchDriver(
config["driver"][args.driver]["xorg_file"],
prioff=config["driver"][args.driver]["xrandr_offload"],
mload=config["driver"][args.driver]["modules_load"],
mblacklist=config["driver"][args.driver]["modules_blacklist"],
moptions=config["driver"][args.driver]["modules_options"]
)
if res is True:
print("Relogin or reboot now, please")
else:
print("ERROR\n%s" %res)
else:
#print("Unrecognized driver name, choose from %s" %" or ".join(list(config["driver"].keys())))
print("Possible drivers: %s" %" or ".join(drivers))
else:
# No driver specified, show current used
output = Info().returnCurDrivers()
for k,v in output.items():
#pci = v[0] # not needed, also in "info"PCI_SLOT_NAME
card = v[1]
info = v[2]
print("GPU%i: %s\n%s" %(k,card,info))
- if you use above script you can switch driver with e.g. ./script-name -d intel
- you can mess around with loaded/blacklisted modules, used xorg.confs:
save current config with ./script-name -s filename
edit and ensure json not broken (dont use python booleans, use true and false instead) - use with ./script-name -c filename -d driver-name
Short summary:
-
deinstall unneeded and install needed packages (with mhwd)
-
adjust xorg.conf (symlink from /etc/X11/xorg.conf.d/90-mhwd.conf to /etc/X11/mhwd.d/config)
-
ensure right modules are loaded/blacklisted
-
nvidia: ensure xrandr setprovideroutputsource command and xrand auto command are executed
-
issues: check /var/log/Xorg.0.log
-
check arch webpages (https://wiki.archlinux.org/index.php/NVIDIA_Optimus and prime webpage)
-
if something goes wrong, is misconfigured, etc..., you likely end with black screen, if using a dislay manager switch to another tty and check /var/log/Xorg.0.log (e.g. with grep -E 'WW|EE' /var/log/Xorg.0.log )
-
you may need or want to use additional options in xorg.conf file
-
nvidia-uvm module is cuda related, should also work without loading
-
dont blame me if you broke your x server