Incorrect frame rate on Linux with Multi-monitor setup

My setup is two monitors, one with 120Hz and another with 60Hz. Window.flip() runs at 60Hz even though the window is (correctly) presented to the 120Hz screen.

If I disable the 60Hz monitor, I get 120Hz, but I need both monitors to be active during the intended experiment. Switching the primary display does not help. Disabling Fullscreen does not solve the problem either.

What should I do to get 120Hz?

Thanks for help!

Info: Psychopy V1.85.2, Linux Mint 18.2 Cinnamon, Nvidia 375.66 driver

Hi Matus,

This is more a hardware problem than a PsychoPy problem.

How are you connecting your multiple monitors? Do you want them to mirror each other, so both screens show the same thing, or run them as separate screens. What cables are you using to connect the different monitors to your PC? Are they mounting onto the same graphics card?

It could be this frequency halving bug previously reported here.

The workaround (identified at that link) is to turn off waiblanking, for example:

self.win = visual.Window(screen=1, fullscr=True)
self.win.waitBlanking = False

On my Ubuntu 16.10 system running on a Zotac Zbox Magnus EN970 with Psychopy version 1.84.2
that setting synchs to retrace but at the monitor frame rate, not 1/2 the monitor frame rate.

best,

Allen

The workaround (identified at that link) is to turn off waiblanking, for example

This is the typical solution for multi-screen setups. There is no guarantee vertical retrace signals are synchronized, even when outputs are from the same graphics card. Issuing buffer swap/flip calls near vertical trace boundaries locks up the program thread until the respective window’s back buffer is available, this may cause the other window to miss its own display’s vertical trace signal.

(hit delete instead of edit on my last post, not enough coffee today)

There is no guarantee vertical retrace signals are synchronized

Well that is a point. Setting waitingBlanking to False caused the inter-frame intervals as measured using getTime() to drop to the expected period for the nominal monitor frequency and they remained regular, ± some tiny fraction of a blanking interval, so I assumed it had worked. However I did not test directly if drawing was synchronized with the refresh on that display. Yes, there is the possibility, given those results, that it synchs to the retrace on the other display, the one which I am not drawing on.

By the way, synching is working perfectly for me with C++/OpenGL/GLFW on these systems and I know in that case drawing is locked to the retrace on the correct monitor because I have external hardware which detects that. That suggests the bug might be somewhere in Pyglet or PsychoPy, as opposed to it being in the driver. Or otherwise perhaps under Pyglet and above the video driver if that is different than what is between GLFW and the driver.

best,

Allen

By the way, synching is working perfectly for me with C++/OpenGL/GLFW

…However I had to create an xconfig file which places each monitor on its own screen to get GLFW to synch correctly, and I am not using that configuration now with this Python testing, so the inferences in my previous message about where the bug might do not seem correct.

  • Allen

Looks like it might be in Pyglet, here.

best,

Allen

1 Like

Thanks for replies.

Sammi asked for more details. The two monitors get two separate displays. They are connected via DP (120hz) and DVI to the discrete Nvidia graphics card. I don’t believe this is a hardware issue, since as mentioned I get 120Hz once I disable the other monitor.

I can reproduce the issue mentioned by Allen, alas it stacks on top of my issue. I’ve already turned of SyncVblank in Nvidia settings. If I turn it on (and use waitBlanking=True) I get 30Hz on the 120Hz display :frowning:

Indeed this seems to be the case. I did couple of experiments with dual monitor setup by varying the monitors, their resolution and by using different cables.

It appears that Psychopy always takes the refresh rate of the first available output in the order listed by xrandr. In my case the order is DVI-I-0, DVI-I-1, HDMI-0, DP-0, DVI-D-0, DP-1

Looking at the order it suggests that it should be possible to present at 120Hz by linking the fast monitor to HDMI-0 and the slow monitor to DVI-D-0. Indeed this works. However, in the above scenario I have to run the fast monitor at 1080p while its native resolution is 2560x1440. I need DP to get 2560x1440@120Hz. Unfortunately, the display port output DP-1 is the last in the list, so its frame rate will be always overridden by the other display. I’m not sure what DP-0 is. The card has only 1xDP, 1xHDMI and 2xDVI. My guess is that DP-0 becomes available with a dual DP splitter.

EDIT: Upon some more thought, my current output constellation suggests the following solution: Link the slow monitor to DVI-D. Link the fast monitor through both HDMI and DP with 1080p@120Hz and 1440p@120Hz respectively. Point the monitor to DP. Point Psychopy to the screen at DP. Now I get the correct refresh rate and the window is displayed correctly as well.

EDIT2: It turns out the issue only affects proprietary nvidia linux driver. Nvidia Windows driver and nouveau work fine.

Sorry, been away so didn’t see these replies.

Seems clear the issue is happening due to interacting with the monitors independently. I set up testing space for my lab, using dual window displays, and have the participant screen operating at up to 144Hz (DP cable), with the other screen at 75Hz (capped by the DVI cable). I would’ve suggested a quick fix so you can test as just mirroring displays, and they operate easily at different refresh rates but they’re stable.

Glad it’s working and you found the cause + fix for the situation!

Some helpful tips from PTB’s SyncTrouble (http://docs.psychtoolbox.org/SyncTrouble) manual page regarding multiple monitor setups. These seem to be general enough to be helpful with PsychoPy.

→ On dual/multi display setups MS-Windows allows you to assign one
monitor the role of the “primary monitor” or “primary display”. It is
important that the display device which you use for stimulus presentation
is the “primary display”, otherwise random things may go wrong wrt. sync
tests and timing.

→ If you have the choice to set your multi-monitor configuration to
either “dual display mode”/“dual display performance mode”/“separate
displays” or instead to “extended desktop mode” or “horizontal spanning”,
you should choose “extended desktop mode” or “horizontal spanning” modes
for best timing and stimulus quality. Please note that this choice
doesn’t exist anymore on Windows-Vista and later.

→ On all operating systems in dual display or multi display mode it is
important that you configure both displays for exactly the same color
depths, resolution and refresh rate if you want to present stimuli across
multiple displays, e.g., for binocular stereoscopic presentation on a
dual-display setup. If there is some option you can choose for “genlocked
modes” or “genlocked modes only”, choose or enable that one. Failing to
configure dual display setups like this will cause massive timing
problems or tearing artifacts on one of the display if you do dual
display stimulation. It may also cause failures in timetamping.