flyinghead / flycast

Flycast is a multiplatform Sega Dreamcast, Naomi, Naomi 2 and Atomiswave emulator
GNU General Public License v2.0
1.36k stars 168 forks source link

Framerate hiccups #649

Open vanfanel opened 2 years ago

vanfanel commented 2 years ago

Platform / OS / Hardware:

Debian 11 GNU/Linux

Github hash: 2319a00c4f5b2b89d030e8e499baf85d62da2c6b

Hardware: x86_64, Vulkan API 1.1. Device AMD RADV STONEY (ACO)

Description of the Issue

Internal framerate seems to differ from host physical framerate, resulting on small hiccups in framerate, even on ~60Hz screen and with VSYNC set ON.

It can be easily detected with the scrolling test in Dreamcast 240p test suite available here: https://artemiourbina.itch.io/240p-test-suite/download/eyJleHBpcmVzIjoxNjUzODI0ODA1LCJpZCI6OTY5MjE3fQ%3d%3d%2eBElnDYkoxUC4pyZlF7lvoK4dEMo%3d

Debugging Steps Tested

Simply try the Dreamcast 240p test suite, enter the scroll test, and observe scrolling smoothness for a while.

Logs Gathered

manuel@vader:~/src/flycast/b4$ ./flycast ~/Downloads/240pSuite.cdi                                                       
00:00:564 sdl/sdl.cpp:564 N[RENDERER]: Monitor refresh rate: 60 Hz (1366 x 768)
00:00:588 rend/vulkan/vulkan_context.cpp:234 N[RENDERER]: Vulkan API 1.1. Device AMD RADV STONEY (ACO)                   
00:00:621 rend/vulkan/vulkan_context.h:261 N[RENDERER]: Using depth format D32SfloatS8Uint tiling Optimal                
00:00:622 rend/gui.cpp:270 N[RENDERER]: Screen DPI is 101, size 1366 x 768. Scaling by 1.00                              
00:00:665 rend/vulkan/vulkan_renderer.cpp:31 N[RENDERER]: VulkanRenderer::Init                                           
00:00:684 hw/mem/_vmem.cpp:494 N[VMEM]: Info: nvmem is enabled, with addr space of size 4GB                              
00:00:711 rend/vulkan/vulkan_context.h:261 N[RENDERER]: Using depth format D32SfloatS8Uint tiling Optimal                
00:00:718 hw/mem/_vmem.cpp:589 N[VMEM]: BASE 0x7fe037ff0000 RAM(16 MB) 0x7fe0c3ff0000 VRAM64(8 MB) 0x7fe0bbff0000 ARAM(2 MB) 0x7fe0b87f0000                                                                                                       
00:00:742 hw/mem/_vmem.cpp:494 N[VMEM]: Info: nvmem is enabled, with addr space of size 4GB                              
00:00:763 hw/mem/_vmem.cpp:589 N[VMEM]: BASE 0x7fe037ff0000 RAM(16 MB) 0x7fe0c3ff0000 VRAM64(8 MB) 0x7fe0bbff0000 ARAM(2 MB) 0x7fe0b87f0000                                                                                                       
00:00:812 imgread/common.cpp:94 W[GDROM]: Warning: CDI Image Loaded! Many CDI images are known to be defective, GDI, CUE or CHD format is preferred. Please only file bug reports when using images known to be good (GDI, CUE or CHD).           
00:00:812 emulator.cpp:55 N[BOOT]: Game ID is [T0001] 

My personal guess here is that the emulator regulates the framerate internally, instead of relying on the vsync. When vsync is ON, the emulator should NOT regulate speed internally: it should run "as fast as possible" and vsync will limit the speed. An option for this could be the solution if I am right on the internal speed regulation guess.

flyinghead commented 2 years ago

Anything different from https://youtu.be/6n1ZEO9abDU ?

vanfanel commented 2 years ago

Anything different from https://youtu.be/6n1ZEO9abDU ?

Hi! Well, there's no possible way a youtube video can show precise framerate, since there's youtube compression, framerate, and playback software in the middle, while flycast renders the graphics in realtime using my local GPU.

Also, that video is 5 seconds long: hiccups can take way more seconds to happen.

flyinghead commented 2 years ago

This video is short but it's 60 FPS and the compression shouldn't be a problem given the resolution.

FYI Flycast doesn't do any kind of internal framerate pacing and lets the game in full control so there's nothing to tweak there.

Having a duplicate frame every couple of seconds or so is what I consider normal. If you have more than that you should look at your settings.

vanfanel commented 2 years ago

Having a duplicate frame every couple of seconds or so is what I consider normal. If you have more than that you should look at your settings.

Hm, I would say that those duplicate frames is what I call hiccups :) So yes, I mean these.

Why is that normal? I mean: that shouldn't happen (it certainly doesn't happen on a Dreamcast) and it's perfectly possible to force emulation to sync with the host rate.

For example, Redream doesn't show that behaviour.

vanfanel commented 2 years ago

@flyinghead I have also noticed that the Libretro builds have the exact same behaviour (ie: erratic hiccups every few seconds). So I believe it's emulation speed, which could be made to match the host refresh rate with an option. Many emulators do this (in Retroarch, almost every core does this).

ghost commented 2 years ago

Sounds like a duplicate of #520

71knight commented 2 years ago

@flyinghead I have also noticed that the Libretro builds have the exact same behaviour (ie: erratic hiccups every few seconds). So I believe it's emulation speed, which could be made to match the host refresh rate with an option. Many emulators do this (in Retroarch, almost every core does this).

Hmm..... I have flycast on retroarch for my Android phone and don't have any hiccups on the 240p test suite with the Sonic the hedgehog scrolling test. You might want to redo your estimated refresh rate in retroarch video menu. Then go to audio latency and go lower step by step, for example 96 then 64 till video hiccups go away.

vanfanel commented 2 years ago

@71knight I have very little deviation on my estimated screen refresh, like 0.2%.

I have reported issues like this many times before on different cores, and I have been told silimar thins ("I can't see it", etc), and then, years after that, more people notices and a fix is done.

BParks21 commented 1 year ago

Sync to host refresh and duplicate frames should be available on all emulators. Not just for one renderer either.

vanfanel commented 1 month ago

Going back to this, RetroArch core is perfectly smooth with 60FPS games, and with 30FPS games if "Full Frame Buffer Emulation" is activated.

But with standalone Flycast, there's no way to achieve perfect movement with 60FPS games, with a duplicate frame every couple of seconds or so as @flyinghead said. Wouldn't it be possible for the games to sync to host refresh? Works for PPSSPP and PCSX2: both have that setting and there are no duplicated frames. I would add such a setting if I knew how...

However, if the core runs on Libretro, it means it can sync to external refresh rate! So it should be easily doable, shouldn't it @flyinghead ?