-
Notifications
You must be signed in to change notification settings - Fork 181
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
Slowdown with framebuffer emulation enable (GLES) #592
Comments
@gonetz Is it really necessary to update on The dummy swapbuffer happens when |
Yes. Look:
I set conditional breakpoint: gDP.colorImage.changed == 0 && (*REG.VI_ORIGIN != VI.lastOrigin) The situation is different in game. The breakpoint triggered the first time only when I closed to the bridge. The question is why dummy swapbuffer may cause slowdown? It is just render one screen-size texture rectangle. Your draw calls graph looks strange after the red line. Before the line number of calls is almost constant. After the line we see cyclic drops to zero followed by peaks, where number of calls is almost doubled. What causes these drops and peaks? I suspect that drops correspond to dummy swapbuffers which take only few commands. But what causes the peaks? Probably number of birds, which are polygonal, not just a sprite. Please remove gDP.colorImage.changed != 0 condition, which is useless for this game and check performance again. |
Thanks for the detailed explanations, very instructive!!!
That's correct! Here's a new graph without gDP.colorImage.changed != 0 condition: Birds appear after the red line and the number of draw calls jump from ~110 to ~190 Also no more slowdown with removed condition ;-) |
Interesting, why no more slowdown? Is it so expensive to draw one additional screen-size texture rectangle and swap buffers? Dummy swapbuffer does not cause slowdown with Mario head. Or does it? Could you test performance of Mario head scene with and without the "gDP.colorImage.changed != 0" condition? |
Just checked and yes it's also slower in Mario's head scene!
Sounds weird indead! But I think swapbuffer is the cause here. If I switch off framebuffer emulation and force swapping buffers 2 times per frame I get similar slowdowns. It's worth mentioning that it's not naticeable at 100% speed but only if you try to speed up the emu (it just won't speed up). |
Thanks for testing! The results are informative. |
That might probably be the case on low end android device that's why I track it down in the first place ;-) |
Is quake2 the only game which requires the condition? |
I don't know. Quake II is the game, for which I added that condition. Probably it is the only one such game. I don't have time to test all games. |
Hum the eglswapbuffer beeing slow seems to be a common issue on android damn! |
Just thinking out loud but what would happen if we force to swap buffers only on last vi update, so no matter if a game is using double or even tripple buffering, swapbuffer will be called only once per frame? |
"last vi update" - what is it? Regarding buffer swap. Actually, it is possible to not use buffer swap at all, and render FBO right into front buffer. Original glN64 works exactly like that. Render to front buffer without buffers swap does not work on Linux for some reason though, so I had to use swapbuffers there. Since it works on other platforms as well, I decided to make it common. Later I found that GLES2 does not support glDrawBuffer command, so swap buffer was the only option. I do't think that eglswapbuffer is a bottleneck, because it does not cause performance problems for other video plugins. mupen64plus-video-gliden64 is close to mupen64plus-video-gln64 in terms of OpenGL usage. It should have similar performance. The main difference is in shaders. GLideN64 fragment shaders are quite large, complex and have code, which is redundant for most games. Shaders simplification probably can boost performance on GLES2 devices. |
Maybe another driver issue! I will make some measurements just to be sure but it seems like the drivers is waiting for completion of eglswapbuffer when it should be mostly asynchronous. |
Blue line: Number of draw calls You can see that the first five dummy swapbuffers are ok but suddenly it takes almost ~9ms to process the function. |
The same problem is present in zelda oot.
Maybe we can make it optional for GLES only? What do you think? |
Does it make visible performance gain on real device? |
Definitely! But don't hesitate to try on your Note3 if you want to see it in action (and have some time of course). |
I think the worse candidate is goldeneye because the problem is noticeable at 100% speed (actually the game is already slow but the dummy swapbuffer make it even worse) Here's a savestate if you wanna try: |
I believe you. Ok, I'll make "gDP.colorImage.changed != 0" check Quake 2 specific. |
Thanks! I hope it won't break anything else ;-) |
Instead of reducing accuracy for speed, maybe the right answer would be to have a config parameter to enable/disable this check. This check could be disabled by default and a warning could be provided to a user that enables it saying that it "will improve accuracy but reduce performance". I believe this is the approach that Dolphin uses. |
It's not exactly accuracy VS speed problem. This check is a workaround for the problem, which probably exists for only one game. If the problem is more common, solution can include new config parameter. |
Here's a video of the slowdown, it happens while the birds start flying out of the tree (game speed is set at 250%)
https://dl.dropboxusercontent.com/u/27654797/mupen64plus-ui-console%202015-06-25%2018-21-00-29.avi
This seems to be caused by a dummy swapbuffer, here's a statistics graph showing draw calls (the slowdown starts after the red line ;-))
And here's a list of GL calls during the dummy swapbuffer:
Sounds like a useless call to ``FrameBufferList::renderBuffer(u32 _address)` ;-)
The text was updated successfully, but these errors were encountered: