RetroArch icon indicating copy to clipboard operation
RetroArch copied to clipboard

MacOS: ProMotion 120hz V-sync not working properly

Open personaone opened this issue 2 years ago • 15 comments

First and foremost consider this:

  • Only RetroArch bugs should be filed here. Not core bugs or game bugs
  • This is not a forum or a help section, this is strictly developer oriented

Description

Looks like when using ProMotion on the 120hz displays, there's no good way to enable vsync nor does the Sync to exact content framerate option seem to work. Doesn't matter if Fullscreen or windowed.

Expected behavior

Locked vsync

Actual behavior

Frame pacing and interlaced content shaking

Steps to reproduce the bug

  1. Enable Vsync and launch a game on a 120hz promotion display
  2. Enable sync to exact content framerate and launch a game
  3. [and so on...]

Bisect Results

This works fine when forcing 60hz from the display control panel, affects only promotion

Version/Commit

You can find this information under Information/System Information

RetroArch 1.14.0 (Git GIT_VERSION)

Environment information

  • OS: MacOS Ventura 13.1
  • Compiler: [In case you are running local builds]

personaone avatar Jan 05 '23 11:01 personaone

Currently no Pro Motion display available, have you checked this?

https://emulation.gametechwiki.com/index.php/Vsync

Have you tried the GSync/Freesync option, as Pro Motion is a variable sync implementation?

estefan3112 avatar Jan 07 '23 16:01 estefan3112

Yup - i tried syncing to the exact content framerate as described in the issue

personaone avatar Jan 07 '23 17:01 personaone

Bildschirm­foto 2023-01-07 um 19 15 03

And this option? As I understand it, the point is really that vintage games should always run at there actual refresh rate. FBNeo provides you with a handy Force 60 Hz option for 60 Hz monitors. In case of Pro Motion, you might have some luck with the above option (I've never tested it though).

estefan3112 avatar Jan 07 '23 18:01 estefan3112

That’s the option that I’m referring to, doesn’t help much:)

personaone avatar Jan 07 '23 20:01 personaone

Hi, I got hold of an M1 MacBoookPro with ProMotion 120Hz display and can confirm your troubles. Irrespective of the settings I tried, I did not get an entirely smooth scrolling as expected with a variable refresh rate monitor.

After some testing, these settings worked out reasonably well for me: FinalBurn Neo Core Options: force 60 Hz Video Synchronization: enable Vsync, but set Vsync Swap Interval to either Auto or 2 Video Synchronization: Sync to exact Content Frame Rate (GSync Vsync): on

I tested this with a Nightly Build under Vulkan, the (one and only) koio-aio slang shader and Latency/Preemptive Frames activated with 1 frame.

How does this work out for you?

estefan3112 avatar Jan 22 '23 13:01 estefan3112

Hi, I got hold of an M1 MacBoookPro with ProMotion 120Hz display and can confirm your troubles. Irrespective of the settings I tried, I did not get an entirely smooth scrolling as expected with a variable refresh rate monitor.

After some testing, these settings worked out reasonably well for me: FinalBurn Neo Core Options: force 60 Hz Video Synchronization: enable Vsync, but set Vsync Swap Interval to either Auto or 2 Video Synchronization: Sync to exact Content Frame Rate (GSync Vsync): on

I tested this with a Nightly Build under Vulkan, the (one and only) koio-aio slang shader and Latency/Preemptive Frames activated with 1 frame.

How does this work out for you?

Yeah this somewhat helps but the frame pacing is uneven and it's not as locked as forcing 60hz, unfortunately.

personaone avatar Jan 22 '23 17:01 personaone

Right now RetroArch doesn't give the OS the necessary hints that it would like to enable ProMotion support (including frame rates higher than 60Hz). I have a proof of concept working but it is not properly implemented and extremely buggy.

warmenhoven avatar Jun 05 '24 04:06 warmenhoven

So, yeah, I'm also having issues with RetroArch on macOS on a 16" M2 Max MacBook Pro.

Basically... If I have VSYNC enabled, video is perfect, but I have audio issues (little audio pops/stutters every few seconds). If I have VSYNC disabled, audio is perfect, but I have video issues (scrolling/motion is jittery, not smooth).

...That is if I have the display set to 60 Hz. If I set it to ProMotion (dynamic 120 Hz), then RetroArch behaves like VSYNC is disabled. (Good audio + stuttery visuals — mirroring what is described by the OP here.)

I can't find a setting combination that offers both good audio and video at the same time. One or the other is always messed up. (I've messed with audio sync settings, various graphics synchronization settings, different audio and video drivers in RetroArch, ...)

Also, if I use an OpenGL video driver instead of Metal or Vulkan, it doesn't seem to respect the 60 Hz setting that I set for the display in macOS settings? When RetroArch is running full screen, it is stuttery, and RetroArch video settings show that the display is running at higher than 60 Hz. (This seemed to start with Sonoma, I think it was working properly in Ventura.)

The "proper solution" to this I think would be to leverage the option in RetroArch to "Sync to exact content framerate" (mentioned above), so that RetroArch doesn't have to try to sync emulation to the display refresh rate but can run at its own speed, and without the display jitters. But, that setting doesn't work on macOS it seems, or at least, not fully. It does seem to slow down the game to the proper speed if I have both VSYNC and audio sync disabled, which would otherwise cause the game to run at an out of control speed. But, it does not leverage the VRR support from the ProMotion display to render the game smoothly.

So, @warmenhoven, I saw your comment about having a proof of concept working. I see from your PRs that you have been active in improving RetroArch on Apple platforms (macOS/iOS/tvOS) and you also have a WIP "display server for Apple" going on. Do you think that proper ProMotion support in RetroArch is achievable in the near-ish future?

I am not trying to rush you along by any means. I am just trying to get a feel for where things are at and decide if I should experiment with different solutions for retro emulation on macOS, or... just keep waiting.

AaronKelley avatar Jun 17 '24 14:06 AaronKelley

Ha, if you found the WIP display server for apple, maybe you also saw the WIP ffmpeg integration or the WIP coreaudio microphone driver. That branch is a bunch of experiments and incomplete work (or just hacks that are only relevant to me). Sometimes the experiment pans out, sometimes it doesn't work or gets shunted to the side.

I am optimistic that it should be achievable and fix not just these issues but also some dosbox performance problems. No idea about a timeline though. The APIs on the macOS and RetroArch sides that I'm trying to marry are relatively few and straightforward; though, in theory the coreaudio microphone API is also straightforward, and yet I can't get that working at all.

warmenhoven avatar Jun 18 '24 02:06 warmenhoven

Just commenting to say I also have this problem on a 14" m3pro macbook pro - it's a shame because VRR is so nice for emulating oddball systems like wonderswan or arcade in general.

PopeKehoeIII avatar Jul 17 '24 20:07 PopeKehoeIII

According to my research ProMotion is not a VRR display in a typical sense, meaning that the frame hold time can only be adjusted with certain granularity (~4 ms on my 16" M3 Max Macbook Pro), thus I don't believe it can precisely match the native refresh rate of various emulated systems. The best settings I've found so far are:

  1. ProMotion enabled in System Settings (able to go higher than 60 fps, needed for systems like SNES).
  2. Vulkan video driver, output refresh rate set to 120 hz, maximum swap chain set to 2.
  3. V-sync: off.
  4. Sync to Exact Content Frame Rate: on.

This makes the emulation run at proper speed with fairly good frame pacing and low input lag (with 1 frame run-ahead it matches real SNES on CRT), at the cost of some screen tearing (easy to observe in 240p test suite, but largely invisible in real games). If correct emulation speed isn't a concern, it's also possible to get good results with v-sync on, auto swap interval, sync to exact content frame rate off. The result is very smooth, but the input lag is very slightly higher.

Now I was hoping that the same configuration would work even better on an external screen with proper VRR support, however I'm encountering major issues. Everything is OK in the windowed mode, but in full-screen RA grinds down to less than 1 fps even in the menu. It doesn't matter if VRR is enabled for the display in System Settings or not. It appears that something goes wrong in the "Direct" presentation mode (in indicated by Metal performance overlay) on external screens, because things improve temporarily when I force it from "Direct" to "Composited" by invoking macOS overlays (like volume / brightness).

I've tried, increasing maximum swap chain images from 2 to 3, but that instantly crashes the entire operating system. Interestingly, the Metal driver works fine, but it's not supported by as many cores as Vulkan. Unfortunately, Vulkan is completely broken for me on external monitors.

EDIT: External VRR displays are now working correctly for me. The crashes disappeared, perhaps due to update macOS, and I solved the extreme slow down issue by enabling V-sync (note that in combination with "Sync to Exact Content Frame Rate" and a VRR display it doesn't cause the game to run at the wrong speed or create stuttering).

don-raph avatar Jul 21 '24 10:07 don-raph

According to my research ProMotion is not a VRR display in a typical sense, meaning that the frame hold time can only be adjusted with certain granularity (~4 ms on my 16" M3 Max Macbook Pro), thus I don't believe it can precisely match the native refresh rate of various emulated systems.

@don-raph Thanks for the explanation, that certainly explains some things.

The best settings I've found so far are: ..... 2. Vulkan video driver, output refresh rate set to 120 hz, maximum swap chain set to 2. ..... If correct emulation speed isn't a concern, it's also possible to get good results with v-sync on, auto swap interval, sync to exact content frame rate off. The result is very smooth, but the input lag is very slightly higher.

OK, this is actually working fine for me. I swear that I have messed with all of these settings before, except explicitly specifying the 120 Hz output refresh rate in RetroArch, maybe that is what did the trick.

I still get periodic frame spikes (see blip in the HUD graph below), but I can't "detect" it anywhere other than the graph. Video looks smooth enough (to me) and I can't hear any audio pops. I'll have to experiment with a few things some more (i.e. Metal vs Vulkan driver) to see what I like best, but this is the most promising situation I've been in so far.

[Edit] Tried with VSYNC off and it also seems fine, I might actually prefer it this way. I was expecting to notice jitter or tearing, and maybe I can see hints of it if I look really closely and like a very hard vertical edge scrolling by, but like you said, it's basically invisible.

Still wish we could get actual VRR...

AaronKelley avatar Aug 01 '24 18:08 AaronKelley

OK, messed with it some more and ended up still dissatisfied.

With ProMotion on and the refresh rate explicitly set to 120 Hz... VSYNC on = still getting audio pops when something causes a frame drop VSYNC off = good audio, but the tearing is actually bothering me

I did figure out a couple of things, though.

First, I accidentally discovered that VSYNC "stutter" issues are resolved if you set the system to "low power" mode (Settings → Battery). Makes sense, this caps the display refresh rate at 60 Hz, but it seems to respect this better than the setting under "Display". I have caught the system running higher than 60 Hz in RetroArch even if 60 Hz is set, especially if trying to use an OpenGL video driver, and this causes the video stutter to rear up. But, this doesn't happen if you set it to "low power" mode.

I wish that the "Threaded video" option worked on macOS, because that helped me solve audio stutter issues on Windows and Linux with RetroArch before.

Oh wait... I've been doing lots of Windows gaming with CrossOver, and it has been mostly smooth. Can I just use the Windows version of RetroArch? Would that work "better"?

Yes. I got the Windows version of RetroArch running under CrossOver. It doesn't work "out of the box" because it defaults to Vulkan and that will cause it to crash. Adding video_driver = "gl" to the retroarch.cfg will allow RetroArch to start. Everything else seems to work as expected, and GLSL shaders can be used.

(I tried other video backends and the only ones that worked were sdl2 and gdi, which aren't useful, and d3d9, which I think CrossOver/Wine just converts to OpenGL anyway. So, "gl" it is for now. I thought maybe d3d11 or d3d12 would work under D3DMetal, but no, they just crash.)

Running Windows RetroArch with VSYNC on, sync to exact framerate on, threaded video on, and the system set to low power mode (to force 60 Hz), I just had my first no-tearing no-video-stutter no-audio-stutter RetroArch session on this system. (I know having both VSYNC and sync to exact framerate on is "contradictory", but I do get video stuttering if either of them are off.) A little bit of an odd setup, but I can work with this I think.

AaronKelley avatar Aug 02 '24 02:08 AaronKelley

@AaronKelley Thanks for sharing your findings! A couple of thoughts:

  1. I'm not normally experiencing issues with audio with V-sync enabled during gameplay, however I can see what you're talking about because if I create a framerate drop by messing with the compositor things turn bad very quickly. When running full screen macOS switches the application to the "Direct" presentation mode, which is fast but quite sensitive to disruptions caused by OS overlays, like the one that appears when adjusting volume using OS level (as opposed to internal RA volume control). I can however make this mode far more stable by raising Max Swap Chain Images to 3 (still on the Vulkan driver). Have you tried this?

  2. I have no problem with simply setting the display refresh rate to 60 hz instead of adjusting the power settings, but that could be because I generally avoid using the gl driver when at all possible. OpenGL support has been spotty ever since it got officially deprecated in macOS.

  3. "Sync to exact framerate on" completely defeats V-sync for me on macOS. See the frame graphs with it on and off in the same game (60hz, V-sync is set to "on" in both cases):

Screenshot 2024-08-26 at 7 36 25 AM

Screenshot 2024-08-26 at 7 35 53 AM

By the way, the problems I had with an external VRR display are now resolved. I've edited my comment accordingly.

don-raph avatar Aug 26 '24 14:08 don-raph

@AaronKelley Thanks for sharing your findings! A couple of thoughts:

I believe background activity is part of the reason for the random frame drops I get. I usually have two VMs running in Parallels (one Windows, one Linux) and I have found the frame drops to be much, much less frequent if I suspend those VMs. (They're not really doing any busywork, though, just around in case I need to use them.) I might have to do some trial-and-error to see if I have any other background stuff running that could be causing such drops. Still... I only ever observe audio stuttering if I have VSync enabled (and I would indeed prefer to have it enabled).

I'll try max swapchain images = 3 and see how that is with VSync on. I assume this is basically enabling triple buffering? I did try that with VSync off / exact content framerate on, to see if would solve the visual tearing, but it did not.

My results with exact framerate on/off look identical to yours (aside from periodic frame spikes that I had complained about), if the display is locked at 60 Hz.

AaronKelley avatar Aug 26 '24 17:08 AaronKelley