Navi RX 5700 XT - variable vblank doesn't match frame rates in some games, causing stutter and flicker
Unlike #1001 (closed) , this issue doesn't seem to be related to vsync at all, but solely to FreeSync (vsync is kept off, also TearFree): When a game uses a visible hardware cursor, it breaks FreeSync. Edit: I originally assumed it was caused by the hardware cursor in HotS, but there is a report proving that it doesn't cause any issues when running Unigine Valley inside Wine with DXVK which uses a hardware cursor as well.
To reproduce, e.g. start Heroes of the Storm in wine-staging 5.0-rc2. To stay inside the display's VRR range, you can either use an external frame rate limiter like libstrangle or use the game's built in limiter by setting -frameratecap=50 -frameratecapglue=50
in the Battle.net launcher options for the game.
Without FreeSync, the game now renders with 50fps, while the game's visible hardware cursor that is rendered on top still runs at the display's full refresh rate, which is fine and desired.
If FreeSync is enabled, something goes wrong: The game still renders with constant 50fps, but the result looks extremely stuttery and the display shows very noticeable differences in brightness and thus flickering. The used Samsung U32J59 offers to show the actual refresh rate at which the display is running in its OSD, and here we see the issue: Instead of running at ~fixed 50Hz, the display constantly switches between different refresh rates between 50 and 60Hz, causing the stutter and brightness flicker. This happens with both WineD3D and DXVK inside Wine. On Windows, the display correctly runs at ~50Hz when capping to ~50fps when using DXVK.
Also other games like World of Warcraft are affected, while other games (with and without visible hardware cursor) run fine, e.g. The Witcher 3.
So it would appear that the presence of a visible hardware cursor confuses the driver, causing it to tell the display to refresh at improper intervals. When using VRR with a hardware cursor, the cursor should instead be rendered at the interval of the application so that they are in sync. This is the case on Windows.
Used software and hardware: MSI 5700 XT Gaming X
Ryzen R5 3600
Samsung U32J59 4k 60hz display (issue happens with both FreeSync enabled and disabled)
Linux 5.4-rc2 (older kernels don't work better in this regard)
xorg 1.20.6
xf86-video-amdgpu 19.1