Novum / vkQuake

Vulkan Quake port based on QuakeSpasm
GNU General Public License v2.0
1.85k stars 224 forks source link

Taking screenshots occasionally crashes with Vulkan error #747

Closed bubbleguuum closed 2 weeks ago

bubbleguuum commented 2 weeks ago

System:

Taking screenshots with F12 sometimes crashes with either vkQueueSubmit failed or vkDeviceWaitIdle failed error dialog.

To reproduce it, hit F12 possibly several times and fast until it eventually crashes.

vsonnier commented 2 weeks ago

Maybe it is similar to https://github.com/Novum/vkQuake/issues/715 ... Did it work with Prefer layered on DXGI Swapchain setting ?

I'm on 551.86 with a GTX 1050Ti with the setting above and I cannot reproduce but it doesn't say much given the diversity of cards and drivers.

bubbleguuum commented 2 weeks ago

It still crashes with forced Prefer layered on DXGI Swapchain.

I have a hard time triggering this crash on the base game's start map, although I could make it crash once or twice here.

However I can trigger it very easily in a quick save of the Immortal Lock that I have attached (rename to .sav).

quick.txt

To reprod:

bubbleguuum commented 2 weeks ago

Urgh, I found what cause this and it is not vkquake.

I have a 4K 60Hz G-Sync monitor with G-Sync enabled.

Running the game without input lag and no tearing is not straightforward.

First, in-game v-sync on always results in massive input lag. Thus I have to set v-sync off. Then I set the in-game framecap to 60 fps (and "Refresh Rate" in video section also set to 60 Hz), but it results in noticeable tearing.

To workaround this, I have to use Riva Tuner Statistic Server (RTSS) to cap the framerate on vkquake.exe to 59 Hz. 60 does not work and also results in tearing. 59 produces no tearing but it is what is causing these crashes taking screenshots (no issue at all otherwise and framepacing is perfect with no tearing). A value of 60 in RTSS does not cause the issue, so the cause of this crash is likely a weird interaction between RTSS limiting fps to 59, the 60 in-game cap limit and G-Sync doing its thing.

Ideally RTSS would not be necessary and in-game 'vsync on' would result in no input lag, or the in-game 60fps framecap would not produce tearing.

Note that this is not the first Vulkan game that is giving me problem with vsync on resulting in massive input lag requiring to use RTSS as a work-around. The only Vulkan game I had no problem with is Doom Eternal.

andrey-budko commented 2 weeks ago

I can easily reproduce this issue from the provided savegame, but it happens only with r_indirect set to 1 (which causes a lot of other bugs for me).

Win10, GT 710 GPU, driver 456.71 (default drivers installed by windows, this is not a gaming PC)

vsonnier commented 2 weeks ago

However I can trigger it very easily in a quick save of the Immortal Lock that I have attached (rename to .sav). quick.txt To reprod: put quick.sav into immortal sub-folder start vkquake switch to immortal mod F9 to load the quick save hit F12, possibly a few times after moving in the level

Cannot reproduce on my side, even spamming F12 like crazy (creating 50+ screenshots). Here are my configs for reference: vkQuake_immortal_configs.zip

My typical GPU settings in NVIDIA control Panel are:

@bubbleguuum Instead of using a third party tool with bizarre side-effects, did you try to combine Nvidia driver settings like Vsync off / Adaptative + Max FPS + Low latency mode for instance ?

bubbleguuum commented 2 weeks ago

Well I've made different tests with a mix of in-game settings and NVIDIA CP settings. RTSS disabled so it does not interfere with framepacing. I also kept "Presentation method vk/OpenGL" to "Auto" for all these tests. Test also done with in-game "Fullscreen" set to "on" which is the default. Changing it to "Exclusive" did not change behavior below.

The results are a bit puzzling and the fact that there are many factors at play make it quite complex to test and understand.

  1. With G-Sync enabled, the only way to have no tearing nor input lag is:

=> Any setting of "Low latency Mode" (LLM) does not help to get rid of input lag, only framecapping to 59 (or anything below monitor refresh rate within G-Sync range) helps.

  1. Next, I checked if I could find a combination of settings that works with in-game v-sync on, and not resulting in massive input lag and/or tearing.

With G-Sync enabled, that seems absolutely impossible. With G-Sync disabled (making my monitor a 60Hz fixed refresh display), it is possible with these settings:

But there are 2 caveats:

Speaking of frametimes, each and every time I observed input lag and/or tearing, the frametime graph shown by RTSS overlay was very spiky with some frames taking 0.2ms, other 16.6ms and other 33.3ms (approxmatively): imagine the frametime graph looking like a filled rectangle ! When there is no issue, the graph is a flat line with each frame taking exactly 1/59 seconds (G-Sync enabled) or 1/60 second (G-Sync disabled).

If it all seems very confusing and hard to understand, it is. Each time I had to double check my finding to make sure it is correct. Moreover, proper frame pacing with Vulkan vs vysnc vs input lag vs tearing and more generally proper frame pacing on a variety of setups seems to be a common and complex topic if you Google it, and black magic. Yet Doom Eternal got it right. In my experience, OpenGL has less issues with this.

The TLDR of all this, is for no input lag nor tearing and impeccable frame pacing on a VRR monitor (possibly NVIDIA-specific) is to :

As a side note, I'm am not certain uncapped framerates is a good idea: it makes my RTX4080S go 2500+ fps (that's for normal Quake levels, not Immortal Lock), triggering heavy coil whine, which is something I have noticed it does only at insane framerates. Maybe a max fps of 500 or 1000 would be more safe. I think Doom Eternal limits to max 1000 fps, maybe for that reason.

Novum commented 2 weeks ago

host_maxfps defaults to 200

Swap chains are notoriously finicky and the screenshot code directly reads out of the back buffer. I wouldn't be surprised if this is causing driver issues.

Novum commented 2 weeks ago

https://github.com/Novum/vkQuake/commit/40cdc6f718d0b2b8174f56ef41c7f5e9ded1ff89

There is a good chance this fixes it.

bubbleguuum commented 1 week ago

Thanks for the fix.

What about allowing +1 and -1 increments in the UI for Max FPS (host_maxfps) ? As I explained in my long blurb, on VRR monitors you mostly want to cap the framerate a few frames below monitor refresh rate to stay within VRR range for no tearing nor input lag.

And eventually a hard cap at 1000 fps to avoid GPU coil whine ?

vsonnier commented 1 week ago

And eventually a hard cap at 1000 fps to avoid GPU coil whine ?

We can keep the "no limit" setting on the left hand side. Simply go to the opposite scale, it is already clamped to 1000 fps in the interface.

What about allowing +1 and -1 increments in the UI for Max FPS (host_maxfps) ?

It would be more convenient to add a slider for max fps with this level of increment, bringing the "slider with displayed value" feature from recent QS. I have not considered bringing it in before, because I thought of very little value but that may be a good case for it.

bubbleguuum commented 1 week ago

It's great that on the right side it is already limited to max 1000 fps, which I did not know.

But let's consider a player that go into the Video settings and set the max fps to uncapped, because this is what he does in every other game. He has a high-end GPU and now is getting 2000+ fps and (probably) coil whine and high GPU wattage (150W+ observed here on my RTX4080S uncapped). Two possibilities: he immediately notice coil whine, link it to the uncapped fps and undo his choice to something more reasonable. Or he leaves it as this, not knowing better. Since there are no monitor capable of 1000+ Hz, I think it would be a good idea to also cap "no limit" to 1000 Hz (or whatever max "max fps" is allowed in the future).

IIRC, 1 or 2 years ago, there has been a game (an Amazon one I think) that had very high uncapped framerates in its UI that caused problems to GPUs.