hrydgard / ppsspp

A PSP emulator for Android, Windows, Mac and Linux, written in C++. Want to contribute? Join us on Discord at https://discord.gg/5NJB6dD or just send pull requests / issues. For discussion use the forums at forums.ppsspp.org.
https://www.ppsspp.org
Other
10.81k stars 2.12k forks source link

Micro Stuttering/Frame Pacing issue #9736

Open BParks21 opened 7 years ago

BParks21 commented 7 years ago

NOTE: If you are experiencing this issue, it may have multiple causes. See this comment: https://github.com/hrydgard/ppsspp/issues/9736#issuecomment-509018634


Using any API there is in every game a micro stutter or frame pacing issue that occurs randomly. This may be exclusive to windows. I've tested windows 7-10 and many different systems with the same results. It is more prevalent using a monitor at 60hz. The issue is almost gone using a 120hz display. Currently that is the only way to resolve the issue in all my testing. The easiest way to test this is to play a game with complete 360 camera control stand in place and slowly spin the camera around. You will see random stutters or inconsistent frame pacing. This occurs with games running at full speed at all times, vsync on, and frame skipping off. I believe ppsspp is suffering from the same issue the PCSX2 team is trying to resolve here. https://github.com/PCSX2/pcsx2/issues/1437

It would be worth looking into. This is my biggest issue with ppsspp and is very noticeable and unpleasant imo. I've been trying to find a solution to this for years and it is driving me mad. I think the pcsx2 team has pinned it down though. Thanks for your time i really hope you guys look into this and hope it is resolved. I love ppsspp except for this :)

System Specs: Operating System: Windows 10 Pro 64-bit MOBO: Asus Maximus IX Code Processor/CPU: Intel(R) Core(TM) i7-7700k @5Ghz Video Card/GPU: MSI GTX 980 Memory/RAM: 32GB DDR4 @3000Mhz

unknownbrackets commented 7 years ago

Just to note a few things that could be slightly related:

  1. We time at 59.94 FPS (so that games run the same speed as on the PSP), which can cause a slight variance at 60 Hz. I would expect it to be much less noticeable at 120 Hz.

  2. Windows (not sure if this may have changed in 10, though) is not capable of delaying a thread more accurately than 1ms (5.99% of a frame.) When video drivers are multithreaded, etc. it can be hard to avoid slight timing inaccuracy because of this.

I haven't carefully studied the pcsx2 issue, but it sounds like the assumption is that this is related to the DWM. Do you have access to Windows 7 or lower (i.e. dual boot), or know someone who is able to detect this issue accurately on Windows 7? It seems like disabling DWM would be a simple way to validate that assumption.

Unfortunately, although I am using Windows 7, I'm probably not very able to notice microstutter - or else it's not happening to me. I did just try rotating the camera around. It seemed smooth, but then I don't really mind that much when games are an even 30 FPS so you probably don't want to listen to me on that.

You can also enable "frame drop" logging in the settings, and keep the log open. This will make PPSSPP log whenever a frame takes longer than expected from its perspective. It shouldn't happen when just spinning the camera (unless maybe you have crazy texture scaling settings or something.)

You can also enable real clock sync, which will try to sync PSP time and real time more closely (without it, we only sync on the frame, but with it, we sync about every 2ms.) Can't say if this will help or hurt, but if it alters it, it may be interesting.

-[Unknown]

LunaMoo commented 7 years ago

I kind of can reproduce it, definitely not bothersome even on my slower system, drops are rare and tiny I can see frames being dropped only by looking in the log when moving camera around fast for example:

23:15:780 idle0        N[SCEDISP]: HLE\sceDisplay.cpp:484 Dropping frames - budget = 33.37ms / 30.0fps, actual = 33.65ms (+0.28ms) / 29.7fps
Kernel processing time: 7.25 ms
Slowest syscall: sceGeListUpdateStallAddr : 1.13 ms
Most active syscall: sceKernelLibcGettimeofday : 3.90 ms
DL processing time: 1.21 ms
Draw calls: 16, flushes 1
Cached Draw calls: 0
Num Tracked Vertex Arrays: 0
GPU cycles executed: 796 (20.000000 per vertex)
Commands per call level: 78 0 0 0
Vertices submitted: 32
Cached, Uncached Vertices Drawn: 0, 32
FBOs active: 1
Textures active: 1, decoded: 1  invalidated: 1
Vertex, Fragment, Programs loaded: 1, 1, 1

Worth noting it never drops frames with unthrottle so it probably is something related to frame limiter, maybe limiting to 60 as an option instead of 59.94 would work around it.

Edit: NVM I think that's just me being unlucky grabbing first game under hand to test - wolfenstein 3D which yeah is a homebrew and might be buggy;p, I can't reproduce it in any commercial games tested soo far despite still seeing it in Wolf, but that one runs at weird fps by design and this might cause it's problems:]. Maybe the problem here is nvidia specific like with some driver settings/hack. I have only amd, but tested on two windows - 7 and 10 neither had any problems.

mirh commented 7 years ago

Unfortunately, although I am using Windows 7, I'm probably not very able to notice microstutter

I think you can use PresentMon or GPUView to nail just about any problem that may hit the display chain.

Anyway, the problem we are having there now is the insanely retard nvidia driver when going fullscreen.

mirh commented 7 years ago

PCSX2 forum base is pretty retard If you:

Can you try these samples to see if any of them presents tearing (press SPACE to start the animation)? Thank you.

Marcelo20XX commented 6 years ago

Have the same exact problem, followed the GIT builds too and experience the same stutter in any 3d games as the OP, I am on windows 7 and a Nvidia video card. Have free time to test anything as long as I can get rid of this problem. Also I am interested if Unknown Brackets can show us how to sync to 60Hz just to test if this help with this problem, thank you and sorry for the bump...

BParks21 commented 6 years ago

I want this issue fixed so badly. The only thing that prevents ppsspp from being enjoyable for me. Glad to see another person who can confirm the problem.

mirh commented 6 years ago

If you are on windows 7, try to start the emulator with "disable desktop composition" compatibility property checked.

As for the pcsx2 issue, final consensus was that fix is making sure rendering window has WS_POPUP style.

Marcelo20XX commented 6 years ago

I tested both with WDC on and off, same thing, I followed this issue by years and the oldest revision I remember that haven't this (yeah at some point PPSSPP wasn't suffering from this) was version ppsspp-v0.9.1-2005-gdea4668-windows-x86. This version hasn't the microstutter every few seconds BUT has a constant stutter once it gets desynced with the audio, back then Atract3 plugin was new and the core was adapting to it...

One thing that got rid of the microstutter for good was an option called "Atomic Audio Locks" with this you will always get smooth video syncing at the cost of jerky audio...

mirh commented 6 years ago

Well, if you are that into the issue, and you have a "stable" version, then bisecting really is what you could do in the meantime devs check if the window is "properly configured".

Marcelo20XX commented 6 years ago

That's why I am interested in testing Unknown Brackets suggestion, but I don't know where in the source I can set the video to 60Hz...

mirh commented 6 years ago

You can create a custom resolution with custom refresh rate if really any. But it's pretty low probability given this seems a lot of other NTSC emulators (not to mention when PAL is brought in) never reported problems.

As for the audio.. Can't you just "null" it like on pcsx2? (sorry I know nothing about ppsspp)

Marcelo20XX commented 6 years ago

I think I found a way to get rid of the stutter, please test the following build https://drive.google.com/open?id=16-jJjtM3bPAZuxt2Ix_zKZ4Ze6forJzM and report any problems. At least on my end I have butter smooth frame pacing, you need to enable the "Audio Sync (Resampling)" for it to work correctly...

BParks21 commented 6 years ago

@Marcelo20XX Yeah this definitely fixed it. Tested Daxter, Valkyrie Profile Lenneth and Crisis Core. No hitching no stutter no frame pacing issues at all.

hrydgard commented 6 years ago

@Marcelo20XX What have you changed in that build?

Marcelo20XX commented 6 years ago

Basically this:

diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 78ca1d2..75a88c4 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -123,7 +123,7 @@ u64 GetGlobalTimeUsScaled() float vps; __DisplayGetVPS(&vps); if (vps > 4.0f)

Marcelo20XX commented 6 years ago

Well here is the complete diff: https://pastebin.com/taWSHJZs if you are interested. There is a problem though, at least on my end there is constant stuttering after some time of playing (similar to the one I found on the revision 0.9.1) that only goes away after you make the game load a new area or zone or whatever it makes to update it, it can be only in my rig so I need others confirm if they are suffering from the same thing...

BParks21 commented 6 years ago

How long did you play before it happened?

Marcelo20XX commented 6 years ago

I am testing this on FF3 and did the intro cave part until Luneth goes to the open world...15 mins or so

UPDATE: I tested this build like one hour straight running around the town of "Ur" in FF3, entering and exiting buildings and here are my findings: You will get heavy stuttering after entering and exiting a building a number of times or by triggering the game to load data, the stuttering seem tied to the load data routine as I only encounter this problem while zoning...No amount of tweaks or configurations can fix this issue on Windows 7 on my rig BUT...

After battling another hour or so with this stuttering I rebooted this time on Windows XP and as you can guess I got finally no stuttering at all in the OpenGL backend (on the Direct3D it stutters briefly every now and then)...

Well that concludes my testings, I used the following rig: Windows XP SP3 32bits, Windows7 64 bits on a Core 2 Duo Q9660 with a Nvidia 9600GT and 2 GB of RDRAM, I want to point out that the issue may be only on my side as I currently don't have access to a more powerful rig...

I will update if I encounter any remaining issues...

BParks21 commented 6 years ago

I will do some more testing later and get back with you.

unknownbrackets commented 6 years ago

You're not using the timer hack, right? One of those changes for it, so just want to confirm.

-[Unknown]

Marcelo20XX commented 6 years ago

No, I am not using that hack and about the heavy stuttering I was suffering is maybe only on my system because it only happens when there is too much action or there is data that is being loaded from my HD ( which is mechanical BTW) because it doesn't happen in all games, for example I can play Project Diva and the Megamans game without a single hitch from start to finish...

[Unknown] the microstuttering is because as you said before the emu is syncing at 59.94 instead of the common 60hz that most desktop PCs uses, I had the same problem in other emus, for example in DesMume i got the same stuttering every few seconds disregarding if the game ran at full speed or not, but after using the same emu on the retroarch frontend I got smooth scrolling mainly because RA forced the emu to sync at 60hz and resample the audio to not have any issue, like PPSSPP is now doing after the changes I made...

I know the correct refresh is the currently used but there could be an option to force PPSSPP to sync at 60Hz for the people who plays on a desktop PC, just saying...

BParks21 commented 6 years ago

I also get the same stuttering in the standalone Desmume and not the RetroArch version.

BParks21 commented 6 years ago

@Marcelo20XX So far your fix for ppsspp has worked perfectly. I've had no stutter in Valkyrie Profile and I've played for over an hour in one session and my game is running off a mechanical drive. Also i switched to another monitor with the game running and still no stutter at all. I'm gonna play a few other games for roughly an hour. So far so good.

BParks21 commented 6 years ago

@Marcelo20XX After playing Daxter and Kingdom Hearts Birth By Sleep for an extended period of time i did see stutter return. I wonder why it didn't return in Valkyrie Profile. Maybe because VP is 60 fps and the other two are 30 fps?

Marcelo20XX commented 6 years ago

I reduced the issue by checking IO on thread and IO timing method "host" on games that are 30 FPS, 60FPS games doesn't have any visible issues...

BParks21 commented 6 years ago

Doesn't that have potential negative side effects?

unknownbrackets commented 6 years ago

One piece of this puzzle is that some PSP games will internally time themselves based on 59.94, instead of relying on the hardware timing. Since the hardware was 59.94 anyway, it was fine even if you assumed it would never change.

This is why we time based on 59.94, mainly.

Also, if changing IO timing has impact on this, then you've got something else going on than FPS timing. Possibly your disk going to sleep.

The "Fast" IO timing is the same for everyone: you will always get the same bugs. The "Host" IO timing is different depending on your hardware, and other applications running on your system - but definitely won't stutter as much. It's known to (possibly inconsistently) both fix and introduce bugs in various games. It might work 10 times you do something, and then bug out the 11th, only because that 11th time, the timing was vastly different from what real PSP hardware would've had.

Maybe instead of changing all those places, try changing these in sceDisplay.cpp..

float scaledTimestep = timestep;

Change to:

float scaledTimestep = timestep * 1.001f;

And also:

float scaledVblank = timePerVblank;

Change to:

float scaledVblank = timePerVblank * 1.001f;

That would keep the internal game time running at 59.94, but time the "outside world" at 60fps. Make sure you have real clock sync disabled, or adjust that one too.

(not tested.)

-[Unknown]

BParks21 commented 6 years ago

I haven't tested the IO timing but i have this issue even when games are running on my standalone ssd or my m.2 raid config.

Marcelo20XX commented 6 years ago

[Unknown] That could be very possible the cause why I am having smooth scrolling in some games and a little stuttering in others, I saw the same issue in SNES emulation, for example with Super Mario World, no matter the amount of tweaks/hacks on the core emulators it wont give you a perfect smooth scrolling on a LCD monitor, you will get stuttering every few seconds BUT on the other side you could play Donkey Kong Country without any scrolling issues. Seems that Super Mario syncs to the internal 59.97Hz while DKC being a RARE game doesn't care...

One of the games that its stubborn and still give me little stutters from time to time is Dracula X the main game...

Will test your suggestion asap, thanks!

BParks21 commented 6 years ago

What snes emulator, all the snes cores i use in RetroArch are stutter free. Emulators like PCSX2, epsxe, DeSmuME and vba-m give me stutter. Standalone higan gives me a ton of stutter with snes emulation but absolutely zero with the new libretro core. I know that Super Mario World stutter you're talking about. It happens on real hardware too, usually happens when you start running full speed. Thats just how the game is.

mirh commented 6 years ago

the microstuttering is because as you said before the emu is syncing at 59.94 instead of the common 60hz that most desktop PCs uses

Again, this would have to happen in every NTSC games emulator ever - there's something that is missing me if this doesn't seem this 'widespread' The idea of uncoupling console from image presentation looks neat (scaledVblank) .... But isn't that still what a compositing desktop would eventually do regardless?

I know the correct refresh is the currently used but there could be an option to force PPSSPP to sync at 60Hz for the people who plays on a desktop PC

Absolutely not. If really any the program should try to see if 59.94 hertz refresh rate is available (see https://github.com/PCSX2/pcsx2/issues/2059) Which, I'll stress again, can easily be added everywhere.

Emulators like PCSX2 give me stutter

I thought we had already nailed that down ultimately?? (and it had nothing to do with refresh)

BParks21 commented 6 years ago

Yeah PCSX2 in my testing still stutters if you're asking? Only in opengl which is a bummer.

mirh commented 6 years ago

.... Set EnableVsyncWindowFlag=1........ EDIT: in PCSX2_ui.ini iirc

Just ftr, is there anybody in here that is experiencing stuttering, not on an nvidia card?

BParks21 commented 6 years ago

Is that a setting in the .ini? I swear i tested that and it didn't get rid if the stutter but i will test it again to make sure.

unknownbrackets commented 6 years ago

But isn't that still what a compositing desktop would eventually do regardless?

Yes, but only if you have frameskip off, alternate speed off, and use vsync.

If you don't have vsync on, we'll generate 1000 frames for every 1001 1/60ths of a second, so it will reuse a single frame about once every 16-17 seconds. This will be your display/compositor though, so a 120Hz will perform better.

Edit: sorry, got it backwards.

To stress, if you think of this as a "shutter speed" issue, filming something that is happening at a speed outside of your control - you're still getting a smooth picture, overall. Your camera just ends up seeing the same thing twice when the alignment is just wrong, like the effect when you film a spinning fan.

-[Unknown]

BParks21 commented 6 years ago

@mirh Setting EnableVsyncWindowFlag=1 makes no difference i still get microstutter. I even set the .ini to read only because every time i booted a game it would reset. Tested the latest dev build. Like I've said in the past the d3d renderer has never had any stutter. This has always been Opengl exclusive when it comes to PCSX2. If only you guys could get d3d up to par with opengl :(

Marcelo20XX commented 6 years ago

@mirh Test again SMW preferably the level at the right of Yoshi's House, you will see the scrolling will stutter every 12 frames or so, I didn't time it, this is because I suspect that game sync to the internal SNES refresh rate, this happen on every emulator, from zsnes to higan...

UPDATE: Back on topic, I tested [Unknown] suggestion and made a build with his changes and got the same microstutter that I was having before, no it didn't work... the only way for now is to change in all those places I mentioned...

How can I disable alternate speed? it only appears to have 0=unlimited or some value up until 1000...

BParks21 commented 6 years ago

Ok PCSX2 is no longer part of the list of emulators with frame pacing issues, it has been fixed. Turns out i had the zoom level on and set to 100.83 this was causing the stutter to persist even after the PCSX2 team implemented their fix. Setting it back to 100.00 allowed the fix to work properly.

mirh commented 6 years ago

Fine. So the "doing something odd presenting frames to Windows" hypothesis is still there.

Yes, but only if you have frameskip off, alternate speed off, and use vsync.

I cannot see how compositing would be FIFO (frameskip off)? Isn't it supposed to send to display only the most recent frame?

This will be your display/compositor though, so a 120Hz will perform better.

Sure, absolutely and I can see that. But I was starting from the assumption that in the *same* conditions a lot of other stuff never presented the slightest of an issue (e.g. see Wiz happy about pcsx2 - finally) This seemed odd to me.

BParks21 commented 6 years ago

@hrydgard Have you had a chance to look at this? I don't mean to nag. It's definitely a real and noticeable thing, primarly with 30fps games on 60hz monitors. Iv'e been able to reproduce it on practically every Windows 10 system I've had my hands on. Also frame pacing issues are visible in the Libretro port as well. It actually seems worse which is strange with RetroArch having such excellent vsync options.

mirh commented 6 years ago

If somebody wants to help, over on pcsx2 we supposedly kinda possibly have a bisecting range for the introduction of this issue. Problem is, there are like a thousand commits to skim.

hrydgard commented 6 years ago

There's a lot of (tricky) work to be done on frame pacing and latency. For 30hz games, we should probably have a mode to duplicate each frame (enough to duplicate the final blit in buffered mode) to make things consistent for graphics drivers...

mirh commented 6 years ago

Ehrm, seriously, if this is the same problem of pcsx2, it's only something weird going on between nvidia drivers, dwm and non-fullscreen modes. I don't think there should be any problems with the usual "refresh rate mismatches".. Or at the very least, not to such deal breaking extents.

Jaizu commented 6 years ago

Switching Backend to OpenGL (Windows 10, latest relase build) fixed the problem for me.

BParks21 commented 6 years ago

Still the same behavior for me. Are you using a 60hz monitor and 30fps game?

FreezingAlone commented 5 years ago

Just dropping in to see if there's been any progress on this issue? I've noticed it since way back and always thought it was my hardware setup, but I've upgraded recently and I'm still having stuttering issues.

zombone commented 5 years ago

I have resolved the stutter I was experiencing and thought I'd share. I knew the stutter had to be related to v-sync so I did a refresh rate test at one website. It showed 60.002 on my 60hz display so I thought I'd see what it was at 59. After setting the refresh to 59 in the Nvidia control panel, that same test showed 59.940. I remembered reading about emulators using that very same number, so I knew I could be on to something.

Well, I was right! Setting my refresh to 59 has completely eliminated all stutter and it's 100% smooth now! If you guys that are having stutters use a 60hz display like I do, try changing your refresh rate to 59.

PS I also use v-sync because I can't stand tearing and it still has not even the slightest stutter now.

InfluentialDisocvery commented 5 years ago

I have resolved the stutter I was experiencing and thought I'd share. I knew the stutter had to be related to v-sync so I did a refresh rate test at one website. It showed 60.002 on my 60hz display so I thought I'd see what it was at 59. After setting the refresh to 59 in the Nvidia control panel, that same test showed 59.940. I remembered reading about emulators using that very same number, so I knew I could be on to something.

Well, I was right! Setting my refresh to 59 has completely eliminated all stutter and it's 100% smooth now! If you guys that are having stutters use a 60hz display like I do, try changing your refresh rate to 59.

PS I also use v-sync because I can't stand tearing and it still has not even the slightest stutter now.

The screen tearing is terrible on vulkan without vysync enabled in the NVIDIA control panel. I was also experiencing some minor stuttering. It didn't make MHFU unplayable but it was very distracting. Hopefully this fixes the issue as I am using a 60hz monitor and I didn't want to switch to OpenGL.

Thank you for sharing your findings. People like you make the internet a very useful source of information.

InfluentialDisocvery commented 5 years ago

The issue still persists. Hopefully, switching to opengl will fix the issue.

eleriaqueen commented 5 years ago

Hello, I tried unknownbrackets' suggestion and built PPSSPP with scaledTimestep // scaledVBlank modifications, and then tried the build with the suggested IO options off. D3D11 & Vulkan backend were tested. It appears shorter stuttering occurs (2-3 seconds of it) only now it's every 16-17 seconds (!), I really thought this would simply add a single duplicate frame which would have been perfectly fine...

The only thing that consistently gets rid of stuttering is OpenGL which is really funny when you think ATI cards are really weak at OpenGL...

I have a ATI/AMD RX480 graphics card with mid-range intel i7 processor, an SSD and use "load iso to ram" option.