Screen tearing on Nvidia GTX960m
I have two hybrid laptops running 17.04, an old ThinkPad and a P50 (2016). These are Nvidia Optimus machines, both with the 'enterprise class' Quadro graphics and proper hardware multiplexing which cheaper laptops don't have. This renders Optimus problems in linux a bit moot, however, I have optimus working anyway.
I spent quite some time working through this problem, and I present The Answer. If you have my machines, anyway.
My laptops have a bios setting to disable the intel graphics and use only the nvidia card, which it describes as Discrete mode. This requires the hardware multiplexing which the mobile workstation ThinkPads have. In this mode, it is easy to get rid of tearing. This is solution (1). But this may not be an option.
If the Nvidia control panel is letting you choose nvidia or intel, you are in hybrid mode.
If you want to use hybrid graphics, or if you have no choice, it is easy to avoid tearing on external monitors since they are driven from the nvidia hardware. Is the tearing only on the laptop panel, or on external monitors? External monitor tearing is fixed by force pipeline composition, in my experience of the two machines. Full pipleline is not needed. This is solution (2a) but it doesn't stop tearing on the laptop panel. You can turn it on from the nvidia control panel or via the command line (good for a start-up script).
See screen shot below. There is a trick: you need to select an external monitor, not the internal panel, and then click Advanced...
A command line script is below.
But to stop tearing on the intel panel in nvidia prime mode, you need Prime sync. This is the most difficult thing to get working. I use gnome desktop on 17.04, but forget about using gdm3. Stay with lightdm as the display manager. gdm3 has a bug at the moment, it seems to force an wayland session and that's not working. With lightdm, you can enable prime sync for a tear free experience, using the very latest nvidia drivers (which are in a PPA I assume you have discovered). You need to create a new modprobe file named to load after the existing nvidia one, and then you rebuild your initramfs for this (purging and reinstalling nvidia drivers does this as a side-effect, but it takes a bit longer). I'll update this answer with full instructions if this is your situation. It works well now, with the latest drivers (about a week old). Until then, it worked but we got kernel panics. Now it seems stable. There is a forum at nvidia for linux drivers which has a very active thread. So getting prime sync working is solution (2b)
I'm not sure there is much point of Prime sync on my laptop; I can also get what I want by using discrete mode if using multi-monitors (nearly all the time), and when I want long battery life, I swap to prime-select intel under hybrid mode. This means a trip to bios settings, but changing prime mode requires a reboot anyway. In other words, I never really need it, but it does work (now).
If you run hybrid graphics in intel mode, it is easy to fix tearing on the laptop panel, since the nvidia card disappears from the picture (literally). Prime sync is therefore irrelevant. No external monitors, in this case, of course.
On my laptop, I have to use a setting to enable tear-free intel; this is an xorg setting. I have a script prime-select_tim which restores that setting when running in intel mode, and removes it when running in nvidia mode. That's because x wouldn't start in prime select nvidia if this config was still active in /usr/share/X11/xorg.conf.d
You said you had trouble when trying to use the intel profile. I found X to be very fussy with the contents of /usr/share/X11 when running in hybrid Nvidia mode. It works if you add nothing (which is why I have a script which hides my 20-intel.conf file if I change to hybrid nvidia mode).
Also note that you should make sure you have the package xserver-xorg-video-intel installed. The package description implies that you won't need it ("discouraged if your hw is new enough (ca. 2007 and newer)." Despite that, it's essential.
This is solution (3). Note I don't know if leaving this file in xorg.conf.d when in hybrid-nvidia mode still causes problems, I haven't tested that for a while.
This is my 20-intel.conf to fix tearing on the laptop panel when in hybrid-intel mode. It does not fix tearing on the laptop panel when in hybrid-nvidia mode (in fact, even merely leaving this file there may stop X from starting). Only Prime sync can help you.
Section "Device"
Identifier "Intel Graphics"
Driver "intel"
Option "TearFree" "true"
EndSection
~
I worked all this out while using xfce, so I know it works there too. But gnome in 17.04 is so nice I changed. I did not test this in Unity.
== Hybrid Nvidia mode ==
So to elaborate on getting no tearing in hybrid nvidia mode: In this mode the nvidia card renders everything. It can write directly to external screens, so any tearing on external screens is just an nvidia problem. ForceCompositionPipeline was the fix I needed.
You can activate this from the command line. Here's what I do.
#!/bin/bash
nvidia-settings --assign CurrentMetaMode="$(nvidia-settings -q CurrentMetaMode -t|tr '\n' ' '|sed -e 's/.*:: \(.*\)/\1\n/g' -e 's/}/, ForceCompositionPipeline = On}/g')" > /dev/null
I am not the author of that snippet, too magical for me. You can also do this from the Nvidia control panel Advanced, but make sure you click on the representation of the external monitor. The PRIME panel, that is, the laptop panel, does not show this setting
If this does not fix the tearing, I can't help, but it means your problem is an nvidia driver problem, nothing to do with prime or prime sync. I'm using driver 384.59 from the PPA. See http://ubuntuhandbook.org/index.php/2017/02/how-to-install-nvidia-375-39-378-13-via-ppa-in-ubuntu/
To draw on the laptop panel, the nvidia card writes to memory used by the intel card, which then displays it on the screen. This is "Prime". For sure you have this working, otherwise there would be no image on your laptop panel.
But Prime Sync is next level. Getting the two cards synced to avoid tearing needs Prime Sync, something so new that only in the past few weeks have we seen a stable solution. The nvidia driver needs to operate in kernel mode setting, which it does not do by default.
sudo vi /etc/modprobe.d/zz-nvidia-modeset.conf
and use this content:
options nvidia_384_drm modeset=1
which obviously assumes you have a 384 driver.
then sudo update-initramfs -u
otherwise the new text file won't have any effect. I don't care what anyone says about settings in grub2, using this text file is the only thing that worked for me and it's the accepted solution on the nvidia Prime Sync thread.
Don't use gdm3, use lightdm if you currently use gdm3. Hopefully the gdm3 bug will be fixed before Ubuntu 17.10 where it will probably be the default display manager :) If you're not sure, so this:
dpkg-reconfigure lightdm
then reboot.
tim@raffles:~$ xrandr --properties | grep PRIME
PRIME Synchronization: 1
Accepted answer is really good but it doesn't worked for me until I changed (my Nvidia driver version is 390)
options nvidia_390_drm modeset=1
to
options nvidia_drm modeset=1
After rebooting, screen tearing finally disappeared.
Caveat with accepted answer under Ubuntu 16.04
I haven't tested the ramifications but the accept answers says to create the file /etc/modprobe.d/zz-nvidia-modeset.conf
and use this content:
options nvidia_384_drm modeset=1
However that contradicts an existing file in the same directory:
$ cat /etc/modprobe.d/nvidia-graphics-drivers.conf
# This file was installed by nvidia-384
# Do not edit this file manually
blacklist nouveau
blacklist lbm-nouveau
blacklist nvidia-current
blacklist nvidia-173
blacklist nvidia-96
blacklist nvidia-current-updates
blacklist nvidia-173-updates
blacklist nvidia-96-updates
blacklist nvidia-384-updates
alias nvidia nvidia_384
alias nvidia-uvm nvidia_384_uvm
alias nvidia-modeset nvidia_384_modeset
alias nvidia-drm nvidia_384_drm
alias nouveau off
alias lbm-nouveau off
options nvidia_384_drm modeset=0
Just something you should watch out for...
Shorter Answer
A shorter answer based on answer by Tim Richardson. For systems with Skylake processor and nVidia GTX 970M controlling HDMI. Clean install of Ubuntu 16.04 and do none of the other steps in the answer, simply use Dash
to launch NVIDIA X-Server Settings
:
Click the Advanced
button to make Force Composition Pipeline
option available. Then check it and apply changes.
Note there is an option to save the configuration file:
The next step to make your Screen Tearing fix permanent is detailed in ArchLinux. In a nut shell:
- Move
/etc/X11/xorg.conf
to/etc/X11/xorg.conf.d/20-nvidia.conf
- Edit the file and insert 3 lines (show below)
- Save file and reboot (I had to do it twice and hotplug 3rd screen on Thunderbolt 3 USB-C.
The 3 lines to add to /etc/X11/xorg.conf.d/20-nvidia.conf
:
Option "metamodes" "nvidia-auto-select +0+0 {ForceCompositionPipeline=On, ForceFullCompositionPipeline=On}"
Option "AllowIndirectGLXProtocol" "off"
Option "TripleBuffer" "on"
On Linux Mint 19.1, none of this was a permanent fix for me. But it was close. So I made an executable file and put the following contents in it:
sleep 20
nvidia-settings --assign CurrentMetaMode="$(nvidia-settings -q CurrentMetaMode -t|tr '\n' ' '|sed -e 's/.*:: \(.*\)/\1\n/g' -e 's/}/, ForceCompositionPipeline = On}/g')" > /dev/null
Then I put the link to this file in startup applications. The reason I put the sleep 20
in there is to give the system time to be fully booted and up before that command executed, because, for me at least, without that sleep 20
it reliably broke the sound settings. No idea why. But waiting a bit to execute the command resolved that issue. Hope that helps someone.