Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to limit framerate to a specific number ? #14315

Open
Stizzie opened this issue Mar 24, 2021 · 19 comments
Open

Is it possible to limit framerate to a specific number ? #14315

Stizzie opened this issue Mar 24, 2021 · 19 comments

Comments

@Stizzie
Copy link

Stizzie commented Mar 24, 2021

I'm having a problem with Midnight Club 3 LA Remix
The game runs 30fps in heavy areas or races, and try to reach 60fps in certain area.
My device runs fine at 30, but only manages to reach 45-58/60 ( Choppy sound and slowdowns)
This also happen in few other games:
Tomb Rider
Spiderman 3
MC3 DUB edition

Frameskip comes in handy at 60fps, but it also skip 1 frame at 30fps, making the game runs 25/30.
Adjust CPU clock speed causes really weird fps like 20/24/44/55/59

If only I could have to game run at 30,40 or 50 fps. It would be perfect

@hrydgard
Copy link
Owner

Closest thing might be auto frameskip, but it's not great.

It's a valid idea to automatically switch the frameskip when the detected framerate changed, to achieve a target framerate. I'll keep this open as a feature request.

@hrydgard hrydgard added this to the v1.12.0 milestone Mar 24, 2021
@LunaMoo
Copy link
Collaborator

LunaMoo commented Mar 24, 2021

Don't we already have that feature to skip frames at 60 while keeping 30 unskipped? At least that's what I understand was the point of that other frameskip type. Not at home and don't remember it's name, but pretty sure it was made exactly for that.

@hrydgard
Copy link
Owner

hrydgard commented Mar 24, 2021

I don't think that's what it does, but I never quite understood it heh :P

@Stizzie
Copy link
Author

Stizzie commented Mar 24, 2021

Don't we already have that feature to skip frames at 60 while keeping 30 unskipped?
Auto frameskip does exactly that, but not perfectly. Sometimes it skips at 30 to 28/29 and makes annoying shutter although when un-checked the device still able to run 30 full speed. Also when it skip at 60 the fps is not exactly stay 30 but varies from 30/31/34

@LunaMoo
Copy link
Collaborator

LunaMoo commented Mar 24, 2021

You'd probably better to patch the game to run at constant fps. It would become lighter as well(assuming down patching to 30).

Anyway I ment this: #11523
As I understand this was made to skip % of frames, so skipping constant % that results with just 1 frame at 60 FPS will skip 0 when game runs at 30 FPS. At least that's how I understood justification for adding it from discussion before the final PR with that feature was opened, never really tested how it works.

@MrHuggles
Copy link

I was actually just coming to post about this, so I'm glad others have brought it up. I've tried adjusting the cpu clock and using frame skip, but those didn't work (frame skipping was actually bad since when the game changes the fps cap from 60 to 30 you go below 30).

My issue with this is that in Final Fantasy Tactics: War of the Lions the max fps value keep changes wildly based on what is happening (such as dialogue moments interspersed throughout combat). Me and a few others on discord think that some way to lock fps to a given max would be a nice feature. Someone on discord report it happening in Dirt 2, as well (i think when played on android).

The reason frame skipping doesn't work is that it "skips" rendering a given amount of frames. For example: if a game runs at 60 fps and frame skip is set to "skip every 1 frame" it will only render every other frame (e.g. Frame>Skip>Frame>Skip>etc.) bringing 60fps down to 30 since only half of the frames are being rendered. If a game dipped to 30 while having frame skipping set to 1 it would result in 15 fps out of a possible 30 (if 30 was the frame cap).

Having games with variable frame caps makes frame skipping an impractical fix. What causes the variable frame caps is probably the better way to understand the issue and hopefully get a fix put into development (be it a patch to code or a new feature like an adjustable frame cap or toggle for frame cap at a given interval).

I made a short video to help highlight the variable fps found in game. It seems to be what others have been experiencing across a variety of games. Perhaps it'll help in some way.

Video for demonstration purpose - https://www.youtube.com/watch?v=ZexnZzUsk-A

@LunaMoo
Copy link
Collaborator

LunaMoo commented Mar 24, 2021

Games are coded to have variable FPS, that's not a bug. You'd have to patch the game code to change it, it's nothing on the emu side althrough sometimes overclocking emulated PSP CPU can give a stable 60, but it still depends on the game, also even when that would work, it would make the game even harder to run on potato hardware.

@anr2me
Copy link
Collaborator

anr2me commented Mar 24, 2021

Btw, how does games usually change the FPS? using a certain syscall? (which syscall?), or changing the CPU clock?

@LunaMoo
Copy link
Collaborator

LunaMoo commented Mar 24, 2021

I don't think there's an "usual" way.

There's like one game which literally checks the number of NPC's on the screen and reduces FPS based on that down to some single digit value even if it easily runs at PSP with default 222mhz clocks with this patched... potentially there's no two games doing this the same way unless using same engine/programmed by same people.

@unknownbrackets
Copy link
Collaborator

unknownbrackets commented Mar 25, 2021

We could allow a target FPS to be entered, such as even 45. And only frameskip above it. That's technically feasible, though a little complicated.

FPS is actually detected. Technically speaking, the PSP has a fixed 59.94 FPS at all times. However:

  • Games can call sceDisplaySetFramebuf() to swap buffers, and most (but not all, and some of the most popular ones are in that exception category) do. In those games, this is called at the desired FPS interval (i.e. 30 FPS / etc.)
  • Games do not need to redraw the scene every frame. They can leave the previous frame intact. On a PSP at 59.94, this would simply continue displaying the same frame, but calling this "59.94 FPS" instead of 29.97 FPS because every other frame gets reused isn't really true.
  • Some games never swap buffers, but instead copy data to the screen with hopefully careful timing (otherwise it could cause tearing on a real PSP.) Again, this happens at their FPS interval.
  • Many games, between frames, will call functions like sceDisplayWaitVblankStart() or sceDisplayWaitVblankStartMulti(), which wait for a specified number of "vblanks" which occur once per 59.94 frame. sceDisplayWaitVblankStartMulti(2); is a pretty clear indication of a 30 (actually 29.97) FPS game.
  • Some games will explicitly calculate the number of milliseconds since the last frame to enforce 29.97 FPS (or even, in some games, incorrectly enforce 30 FPS.) They'll delay or loop until the milliseconds have passed.

But technically speaking, one could say that all PSP games are technically 59.94 FPS. They technically provide the display controller with a frame and the hardware does an update of the LCD at that interval.

PPSSPP will however show 20/60 if the game is only drawing or updating the framebuffer 20 times per second. This is what people want/expect from an FPS limit.

Inherently, this is why it's complex to limit the frameskip to an arbitrary amount. The process is like this:

  1. The game finishes rendering a frame and we detect it has changed.
  2. As an optimization, we hide unchanged frames so the OS and graphics driver don't pay the performance cost of displaying duplicates (i.e. we convert a 59.94 FPS game that only renders 30 times per second to a 30 FPS game.) There's an option to force sending every frame to the OS, which can help microstutter.
  3. We now have to decide: until the next frame completes, should we: (a) ignore all drawing commands and skip them or (b) process them. If we skip this frame, we choose (a).
  4. At this point, we could say how many frames of the last 60 vblanks we skipped. So in theory we could keep a trailing count and if we've skipped less than 30, skip this next one.
  5. Things get tricky during transitions or videos. The game may start rendering "off track". For example, they started rendering like this: Y N Y N (30 FPS, every other), but then a video started and it looked like this: Y N Y N N Y N Y. If we keep skipping the odd ones, we'll suddenly show nothing (only doing the Ns starting at the doubled N.)

-[Unknown]

@MrHuggles
Copy link

Wow!
You know your stuff, Unknown Brackets.
I learned something here. I hope someone more capable at coding sees your post. It's sure to help get things rolling on a feature like this.

@Stizzie
Copy link
Author

Stizzie commented Mar 27, 2021

I have came across #2542 and #11843 lately
Wonder if they provide solution to this ?
the ForceMaxFPS=60 was not found neither in the UI nor the PPSSPP.ini, and also is it configurable to ForceMaxFPS=[number] ?

@LunaMoo
Copy link
Collaborator

LunaMoo commented Mar 27, 2021

Force max fps was causing insanely long load times or even completely breaking some games, set under 60 to ie force the 60 fps game to run at 30 fps was also reducing the game's speed similar way to using alternate speed set to 50%. The option was removed together with other game breaking hacks to stop users from causing problems to themselves and then reporting those problems as emulation issues, especially since mobile users tend to abuse such hacks even for games that could only suffer from potential problems with no actual advantages, resulting in making their own experience worse.

The only proper way to force the game into actually running at lower fps it was designed for with no disadvantages is to re-program that game itself(not always easy, but usually much easier than increasing FPS). In fact even in the very extreme case of GOW games, you're better to use fan made patches than depend on this particular PPSSPP hack that's applied automatically for it nowadays, it will make the game run smoother and easier to emulate at the same time.

@Stizzie
Copy link
Author

Stizzie commented Mar 28, 2021

@LunaMoo wel Force60fps sounds more appealing according to users feedback in #11843

Why removed ForceMaxFps from settings?
Manual set this parameter to 30 give stable fps in most games.
Star Wars Battlefront 2, Crash Of The Titans, MediEvil Ressurection, Wall-E, Tomb raider anniversary.
If just use frameskip=1 in these games we get 20-30fps and 100-80% of speed.
With manual set ForceMaxFps=30 in ppsspp.ini
We get stable 29-30fps and 100% of speed.

Tomb Raider: Legends need ForceMaxFps=20 to work propertly.

@unknownbrackets I believe #2542 is your work right ? Can it be implemented in current builds, also how was your experience with your hack ?

@LunaMoo
Copy link
Collaborator

LunaMoo commented Mar 28, 2021

The thing is this hack abused as by that user pretty sure still resulted in correct sound speed even when actual physics speed ends up half of what it should be. At least that's my experience when I tried it years ago.
When you try to understand user reports it's kind of obvious that many PPSSPP users that run PSP games in emulator and are willing to sacrifice quality to under what was on PSP and bother to try hidden ini-only settings to do that is actually because they never had any gaming hardware before getting some low end or old smartphone or laptop, they often don't know how those games were running on real PSP and were happy with the results despite the games not running as they should. Lowering max fps on the emu side doesn't actually make games run fine, it's very rare and would work only in some of the games with variable fps that doesn't tie physics to fps and don't get broken by it by any other reason.

Dangerous speedhacks might feel worth using for some users, but will ruin the experience for many other users especially when you look at how many users are firstly getting their "best settings" from some youtube video, then coming for support to our forums trying to figure out why game X doesn't work, or runs without graphics. It's just not that easy to justify helping small percentage of people, if it has known tendency to ruin a ton of other users experience.
Can't tell [Unknown] experience with that hack, maybe it's similar to mine, maybe completely different, however as mentioned earlier in this thread it still exists in PPSSPP and is activated by default in games where it's known to work. You don't need to do anything, where it works and is safe to, it's active by default for you, it was just not safe as an option available for users since as a trend from few years in the back going forward speedhacks that cause problems are removed and where helping a lot without degrading quality are kept activated by default.

As for Tomb Raider Legends, I actually know this case well and from that list above I can certainly believe it actually worked, however that game is bad example of everything that's wrong with popular franchises and console ports. It's actually bugged(even on real PSP) in a way that it has a really poor variable fps system that suffers from slowdowns whenever any change happens. A more quality workaround used by most people is to simply overclock PSP cpu to 333mhz to stop the game from ever lowering fps(even on real hardware with CFW). The fact it has variable fps makes it appear to work 100% fine with lower values on that emu side hack, but if the game goes even lower, you'd still experience the game bug, hence probably why the user set it to 20 there(and not sure if that's even enough as it probably could go lower in some places ~ another problem with user reports, people say that hacks work after testing like 1% of the game which is useless). Either way this is a terrible port, but would still give better experience with a fan made 30 fps patch than going even lower with emu hack and with anything that can run 60fps PSP games normally without performance issues, just overclocking psp cpu is the better way to go. PSP emulation for most people is a way to enhance the original experience, degrading it is not something most users desire.

@unknownbrackets
Copy link
Collaborator

unknownbrackets commented Mar 28, 2021

As you can tell from the low number, I implemented that some time ago (almost 8 years, I guess.) I had misgivings about it then, but hoped it would be a "safe" hack to improve two particular games that render at a breaknext pace.

It didn't turn out safe. Even when it didn't cause major problems, it caused framerate issues (i.e. not hitting 60 consistently even if the device was completely capable) in some games. It also only worked to any degree for games that call sceDisplaySetFramebuf, which is most games but certainly not all.

Remember that there are 1500+ games (not even counting different region variants), so we want to do things generically. We don't write 1500 different versions of components of the emulator for each individual game. We do have some detection of patterns that certain game developers used for some performance stuff, but FPS handling is much more varied.

Game specific patches will always result in better quality FPS limiting than PPSSPP can do generically. The God of War example is a good one - the #2542 change did help performance, but the game patch helps much more. See here:
https://forums.ppsspp.org/showthread.php?tid=22159

But in summary (it's a long post):

And to be clear, God of War is probably the game where that change performed best. In many games, it'll cause more rendering to be built up each frame, and just increase microstutter with no performance benefit.

-[Unknown]

@anr2me
Copy link
Collaborator

anr2me commented Mar 29, 2021

I see, based on the post at forum, GoW (and probably other games with similar FPS issue) is lacking of Vsync and render as many frames as possible, and by inserting vblank using cheat it's doing a vsync to PSP's display refresh rate or half of it.

@ghost
Copy link

ghost commented Jun 8, 2021

This is kinda related to #11372 or not?

@antipirgos
Copy link

My device is weak and i want to limit all my games to 30fps but idk how.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants