Solving the Ubuntu 14.04 – NVIDIA 346 – nvidia-prime black screen issue

For a project that I’m currently helping with, we needed recent OpenGL features that are only available on NVIDIA drivers with version 340 and later.

Unfortunately, I have one of those NVIDIA Optimus laptops. Up to now, Bumblebee worked a treat (I would recommend this system in most cases), but for this project I needed the whole of X to run on the NVIDIA, so I had to make use of nvidia-prime to switch between Intel and NVIDIA mode.

After upgrading to the nvidia-346* packages from the xorg-edgers PPA, switching to nvidia mode by typing prime-select nvidia and then logging out and in to X, I was greeted by a black screen.

Analysis

Many hours of experimentation, script tracing and web searching later I made the following observations:

  • gpu-manager, part of ubuntu-drivers-common (in my case version 1:0.2.91.7), runs every time you start and stop your display manager (in other words, when you log out and back in) and then rewrites the /etc/X11/xorg.conf based on what it finds in the system.
  • In theory, with prime support in the NVIDIA drivers, xrandr is used to connect the output of NVIDIA adapter to the Intel adapter, which then displays the output. See the NVIDIA driver documentation for more details. The 90-nvidia.conf script in /usr/share/lightdm/lightdm.conf.d/ (part of the nvidia-prime package) calls /sbin/prime-offload, which will automatically take care of the xrandr setup for you.
  • gpu-manager was rewriting my xorg.conf file incorrectly, at least according to NVIDIA’s xrandr documentation. The primary issue was that gpu-manager was using the intel driver for the intel, instead of the modesetting driver.

The solution

All of this lead to the following (working: now tested on two setups) solution:

  • Switch to console (Ctrl-Alt-F1) and stop lightdm: sudo service lightdm stop
  • Disable gpu-manager by commenting out everything in /etc/init/gpu-manager.conf
  • Switch to nvidia mode by doing sudo prime-select nvidia
  • Change your /etc/X11/xorg.conf to look like this, making sure that the nvidia BusId is correct (check with lspci):
    Section "ServerLayout"
     Identifier "layout"
     Screen 0 "nvidia"
     Inactive "intel"
    EndSection
    
    Section "Device"
     Identifier "intel"
     Driver "modesetting"
    EndSection
    
    Section "Screen"
     Identifier "intel"
     Device "intel"
    EndSection
    
    Section "Device"
     Identifier "nvidia"
     Driver "nvidia"
     BusID "PCI:1:0:0"
    EndSection
    
    Section "Screen"
     Identifier "nvidia"
     Device "nvidia"
     Option "UseDisplayDevice" "None"
    EndSection
    
  • In the comments, Christopher May-Townsend made this brilliant suggestion. By doing sudo chattr +i /etc/X11/xorg.conf you can prevent any process from changing the file. We highly recommend that you do this, as users have reported that even after disabling the gpu-manager upstart job, it still manages to change the xorg.conf during reboot.
  • Start X up again with sudo lightdm start

If you are still greeted by a black screen, switch back to the console, and double-check that the xorg.conf has not again been rewritten to its pre-modesetting state. (if you’ve used the chattr trick above, you should be fine)

If you want to switch back to Intel you will have to stop lightdm, re-enable gpu-manager, make xorg.conf editable again with sudo chattr -i /etc/X11/xorg.conf, activate intel mode with sudo prime-select intel and then restart X with sudo service lightdm start.

It’s very possible that later versions of gpu-manager might have fixed this behaviour.

Let me know in the comments if this worked for you!