prboom-plus icon indicating copy to clipboard operation
prboom-plus copied to clipboard

Micro stutter randomly occurs

Open Velonox opened this issue 3 years ago • 38 comments

Whenever I use prboom plus 2.6.2 and dev builds above it my game will randomly stutter and skip from frames. I am running the game on a machine that is more than capable of running even the most demanding maps. I also run the game in opengl rendering in case that may be part of the problem. I have notice this also occurs in DSDA DOOM, running the latest version, so the issue can be fundamental to prboom or just my pc.

Velonox avatar Aug 23 '22 13:08 Velonox

Is there any consistent trigger for when it happens? For instance, I've heard some players experience a stutter the first time certain sounds play. Is it completely random or is there a common factor at play?

kraflab avatar Aug 23 '22 15:08 kraflab

Do you have uncappted framerate enabled?

Can you reproduce this issue with capped framerate?

JadingTsunami avatar Aug 23 '22 15:08 JadingTsunami

Is there any consistent trigger for when it happens? For instance, I've heard some players experience a stutter the first time certain sounds play. Is it completely random or is there a common factor at play?

Now that you mention that it is entirely possible that is the case since I remember it happening whenever a new enemy appears. And if that is the case is there anything I can do to resolve it?

Velonox avatar Aug 23 '22 15:08 Velonox

Do you have uncappted framerate enabled?

Can you reproduce this issue with capped framerate?

I have yet to try capping it with turning off uncapped frame however I have tried capping the frame rate via v sync as well as capping it with Nvidia control panel.

Velonox avatar Aug 23 '22 15:08 Velonox

I have yet to try capping it with turning off uncapped frame

Please try capping framerate using the in-game configuration option and see if the issue is resolved.

JadingTsunami avatar Aug 23 '22 17:08 JadingTsunami

I have yet to try capping it with turning off uncapped frame

Please try capping framerate using the in-game configuration option and see if the issue is resolved.

Turning off "uncapped framerate" does resolve the issue however I do prefer the smoothness that comes having a high framerate so I would like to find a way to keep it on.

Velonox avatar Aug 23 '22 17:08 Velonox

Turning off "uncapped framerate" does resolve the issue however I do prefer the smoothness that comes having a high framerate so I would like to find a way to keep it on.

You can try vsync and see if the issue resolves. If not, you will need to play with capped framerate. You can increase the fps limit in dsda-doom to try and find a smooth fps that avoids the stutter.

JadingTsunami avatar Aug 23 '22 17:08 JadingTsunami

Turning off "uncapped framerate" does resolve the issue however I do prefer the smoothness that comes having a high framerate so I would like to find a way to keep it on.

You can try vsync and see if the issue resolves. If not, you will need to play with capped framerate. You can increase the fps limit in dsda-doom to try and find a smooth fps that avoids the stutter.

ok I have been testing that out with some results, is there a recommended fps cap per hz of the monitor?

Velonox avatar Aug 24 '22 09:08 Velonox

can adjusting the "texture options" fix this issue for me? The only change I make to it is turning off "texture filtering".

Velonox avatar Aug 24 '22 15:08 Velonox

Yeah I have been getting this sometimes too. Easiest way to reproduce it for me to is fire up TNT m1 and sit and monitor the frames. It will just randomly dip. Even panning the camera around with the arrow keys is jerky. Settings unlimited framerate/vsync on. I have a 240hz panel too so it will dip from 240-239 to 234 randomly by doing nothing. It happens in DSDA as well, though dsda feels more stable to me. My suggestion would to disable vsync and use RTSS/or nvidia control panel and limit the frames there.

vocaab avatar Aug 26 '22 20:08 vocaab

Yeah I have been getting this sometimes too. Easiest way to reproduce it for me to is fire up TNT m1 and sit and monitor the frames. It will just randomly dip. Even panning the camera around with the arrow keys is jerky. Settings unlimited framerate/vsync on. I have a 240hz panel too so it will dip from 240-239 to 234 randomly by doing nothing. It happens in DSDA as well, though dsda feels more stable to me. My suggestion would to disable vsync and use RTSS/or nvidia control panel and limit the frames there.

Yeah I have done that and it does reduce the issue but it still exists

Velonox avatar Aug 27 '22 01:08 Velonox

so my best solution to the issue to play in software mode since it removes the stutters. Software mode play much smoother than I remember and I like it's lighting so I don't mind it.

Velonox avatar Sep 03 '22 22:09 Velonox

All I can do now is hope the issue is resolved in the next update for either DSDA or PrBoom +

Velonox avatar Sep 08 '22 22:09 Velonox

I think I accidentally stumbled upon a workaround for that problem. I also get some random hitches in PrBoom+/DSDA-Doom from time to time in OpenGL mode (never happens in software mode though). They are almost negligible in my case as I play on g-sync monitor, but I guess this is exactly the problem that others have described here already.

First of all these are my settings (in DSDA-Doom):

videomode "OpenGL" screen_resolution "960x540" use_fullscreen 1 exclusive_fullscreen 0 render_vsync 0 uncapped_framerate 1 dsda_fps_limit 105

The display is set to 120Hz, g-sync mode. V-sync is enabled in nvidia control panel for DSDA-Doom.

It seems like I can consistently eliminate those random stutters by simply changing Exclusive Fullscreen to "on" and then back to "off" for the duration of the level. And apparently the game reintroduces stutters after the map change. But if I go to the options menu and change exclusive fullscreen to on and off again, then once again it will fix random hitches for the duration of that map.

rrPKrr avatar Nov 08 '22 19:11 rrPKrr

Does it have to be exclusive fullscreen or does it get fixed if you switch to software and back to opengl? Trying to find out if reinitializing the video mode fixes it (as opposed to specifically the fullscreen toggle).

kraflab avatar Nov 08 '22 21:11 kraflab

I feel that adding something like "precache_sound" that is used in Woof would resolve the issue since it usually comes up when in sounds are activated such as enemies, getting a weapon, etc.

Velonox avatar Nov 15 '22 02:11 Velonox

I feel that adding something like "precache_sound" that is used in Woof would resolve the issue since it usually comes up when in sounds are activated such as enemies, getting a weapon, etc.

Well, the problem is that after debugging this issue for some time the only hiccup I have managed to catch is SDL_GL_SwapWindow() function... I personally play tha game with 105 fps cap (in g-sync mode), and for 99% of time the whole program manages to finish all calculations in under ~9ms no problem (that is no surprise given how at uncapped fps it can output thousands of frames per second in same scenes), but then at random times and out of the blue, SDL_GL_SwapWindow() can take up to 45-50ms (so basically framerate drops down to ~20 for a split second), and that's where the stutter happens. Unless there are multiple sources of the stutter of course, but once again I have noticed 0 frametime fluctuations caused by sound related code (or any other code really).

Can somebody else time SDL_GL_SwapWindow() and confirm or deny whether this is the case for them?

P.S. @kraflab could you possibly add a function to DSDA Doom that would log accurate times between two points in the code to the text file, without affecting the program too much? I would volunteer for the grunt work and try to catch any frametime artifacts (if there are any besides SDL_GL_SwapWindow()).

NVM, I think the precision of QueryPerformanceFrequency() and QueryPerformanceCounter() would be enough for logs... I will try to find the root of those hiccups.

rrPKrr avatar Nov 17 '22 05:11 rrPKrr

Yeah, so I added a crude function to DSDA-Doom https://github.com/rrPKrr/dsda-doom/commit/2b2b5baced08f3c7f4bdb446eabddf9812d4e0ce , and timed D_DoomLoop(), D_Display() and I_FinishUpdate() while playing E1M1 normally at 105fps (105 is chosen because it's 35x3):

FinishUpdate

As you can see from the log, D_DoomLoop() shows consistent 28-29ms (that's because I use itoa() since approximation doesn't play any role here, as those +/- 1 ms inaccuracies aren't what's causing the problem). During these ~28 ms D_Display() consistently updates every ~9.5ms 3 times and framerate sits at 105. But when the stutter occurs D_DoomLoop() tanks down to ~79ms, and the only place where it spends so much time is I_FinishUpdate(). To be more precise it sits in gld_Finish() > SDL_GL_SwapWindow() for no apparent reasaon.

I thought it was a debugging environment that might have caused these spikes, but now after adding a logging function and playing the game normally I experience exactly the same behavior. ¯_(ツ)_/¯

rrPKrr avatar Nov 17 '22 22:11 rrPKrr

I guess you already implemented a timing solution, but for future reference you are looking for dsda/time. There's an example use here: https://github.com/kraflab/dsda-doom/blob/dcb92d049f30d8b7501f14d6d2fba8a68dfef3cc/prboom2/src/dsda/key_frame.c#L390. Wrapping it in a log to the console would just be a little extra 🙂

This is a really great investigation, thanks for digging in so deep! For the first time I'm feeling really optimistic that it will be solved 😄

kraflab avatar Nov 17 '22 22:11 kraflab

Just a minor update, because I began chasing ghosts after doubting my own findings...

I have simply commented out SDL_GL_SwapWindow(sdl_window) and replayed a demo so that the game could play normally in the background (because commenting out SDL_GL_SwapWindow() makes the game to not show on the screen). No single frame takes longer than ~9.5ms to finish this way. Not even one. So, yeah, now I am 100% sure. 😅

rrPKrr avatar Nov 19 '22 00:11 rrPKrr

What if you play a demo without it commented out? Does it stutter?

kraflab avatar Nov 19 '22 11:11 kraflab

What if you play a demo without it commented out? Does it stutter?

Yes, SDL_GL_SwapWindow() tanks regardless if it's a demo playback or a normal play.

rrPKrr avatar Nov 19 '22 12:11 rrPKrr

And you don't have vsync on I assume?

kraflab avatar Nov 19 '22 13:11 kraflab

And you don't have vsync on I assume?

videomode "OpenGL" screen_resolution "960x540" use_fullscreen 1 exclusive_fullscreen 0 render_vsync 0 uncapped_framerate 1 dsda_fps_limit 105

The display is set to 120Hz, g-sync mode. V-sync is enabled in nvidia control panel for DSDA-Doom.

V-sync is on because it's needed for g-sync to work properly (just to clarify it works differently than your normal v-sync).

But before you ask, no, I have already checked and SDL_GL_SwapWindow() still decides to waste time randomly regardless if it's in a g-sync mode, regular fixed refresh rate v-sync mode or if all syncing methods are forced off completely.

rrPKrr avatar Nov 19 '22 13:11 rrPKrr

We could try different settings for this function https://wiki.libsdl.org/SDL_GL_SetSwapInterval

fabiangreffrath avatar Nov 19 '22 13:11 fabiangreffrath

We could try different settings for this function https://wiki.libsdl.org/SDL_GL_SetSwapInterval

It's controlled by the in-game v-sync option, no? But other than that it can also be set to -1. I have already tried that.

rrPKrr avatar Nov 19 '22 13:11 rrPKrr

Correct me if I'm wrong, but the rendering may be asynchronous to some extent, right? As in, there may be buffered draw commands that are only guaranteed to be done when SDL_GL_SwapWindow returns? If that's the case, then you wouldn't actually know what is slow on that frame, even though the slowdown shows up at the swap.

kraflab avatar Nov 19 '22 14:11 kraflab

Wait a second... After reading this comment https://gamedev.stackexchange.com/questions/181327/are-there-any-good-techniques-for-reducing-or-smoothing-stutter-after-a-longer-f I got curious so I made a completely empty loop using glfw+glew. Just glClear(GL_COLOR_BUFFER_BIT); followed by glfwSwapBuffers(window);

That actually does exactly the same thing as DSDA-Doom. Even the frametime spikes frequency looks the same. Doesn't make any sense.

rrPKrr avatar Nov 19 '22 14:11 rrPKrr

Did you try running the process with the highest scheduler priority?

It's possible the OS isn't scheduling the app every time.

Else you might try DwmFlush after every swap buffers call.

JadingTsunami avatar Nov 19 '22 17:11 JadingTsunami

Did you try running the process with the highest scheduler priority?

It's possible the OS isn't scheduling the app every time.

Else you might try DwmFlush after every swap buffers call.

  1. Well, I've tried now after you've mentioned that. But nah, it does nothing.
  2. DwmFlush did a lot of things. First of all it reduced fps from capped 105 to variable ~92-94 for some reason. Then it changed SDL_GL_SwapWindow() times so that now they matched times spent in D_Display(): dwmflush But, as you can see, at some point SDL_GL_SwapWindow() times still skyrocketed for no reason. So, sadly that made things only worse.

rrPKrr avatar Nov 19 '22 18:11 rrPKrr