Skip to content

Present timing - #5869

Draft
doitsujin wants to merge 20 commits into
masterfrom
present-timing-v2
Draft

Present timing#5869
doitsujin wants to merge 20 commits into
masterfrom
present-timing-v2

Conversation

@doitsujin

@doitsujin doitsujin commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Rebased the work that I already did quite a while ago and (somewhat reluctantly) installed Gnome for testing. Turns out it basically works fine there, both with and without VRR.

TL;DR is that this kicks in if

  • VSync is enabled with a sync interval > 1 or with a "fake" display mode (e.g. 60 Hz on 144 Hz display), or
  • VSync is enabled and the built-in frame rate limiter is used.

Not gonna land this any time soon, this needs a lot more testing on a large number of environments, and I'd definitely want to wait until KWin has some sort of usable commit-timing support upstream. Also currently only works with something like proton-ge + PROTON_ENABLE_WAYLAND=1 for now. X11 is completely untested and XWayland doesn't support this.

Compositor Mesa Mesa VRR XWayland Nvidia Nvidia VRR Nvidia + PRIME Nvidia + PRIME VRR
Mutter (Gnome 50) 1, 4 2 2
Kwin (Plasma 6.8) TBD TBD 1, 4 TBD TBD TBD TBD
Gamescope 1, 4
DWM (Windows) N/A N/A N/A 1 3 N/A N/A
  • 1 Only supports relative timing and not with VRR. Can handle SyncInterval > 1 at native refresh, but not much else.
  • 2 Slightly inconsistent perf
  • 3 Requires enabling FSE
  • 4 Not supported on Nvidia

XWayland only supports relative mode on Mesa and doesn't report VRR, so we'd only use it for the SyncInterval > 1 case there, but hey, it works.

Definitely gonna have to add a config for this as well so peolpe can at least disable it in case of issues.

@bigjoe54321

Copy link
Copy Markdown

I'm using KWin with the latest version of the commit timing PR merged into it while I test this present timing PR in a few of games.

Here's some logs from when I tried to run a D3D9 game with the latest Proton-GE.

hl2_d3d9.log
steam-1583720.log

@doitsujin

doitsujin commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

The validation error about invalid time domain IDs should already be fixed, I updated the branch a while ago to fix an issue with that on Nvidia.

As for why the INCOMPLETE happens, urgh, who knows. I really hate how complex this extension is.

@bigjoe54321

Copy link
Copy Markdown

Unlike that D3D9 game, this D3D11 game does not freeze. Judging by the D3D11 game logs, present timing is working in that game. Let me know if I'm wrong.

For both games, I used the files from the artifact found here: https://github.com/doitsujin/dxvk/actions/runs/33633088810

Here's the logs of the D3D11 game:
steam-311210.log
BlackOps3_dxgi.log
BlackOps3_d3d11.log

@doitsujin

doitsujin commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

To be clear, does D3D9 still freeze even with current code? Makes me wonder if there's any 32-bit shenanigans going on, I've only tested 64-bit games so far (including a D3D9 one though).

@bigjoe54321

Copy link
Copy Markdown

Yes, multiple D3D9 games still freeze with current code. I might test other 32 and 64-bit games.

@bigjoe54321

bigjoe54321 commented Sep 2, 2026

Copy link
Copy Markdown

To be clear, when I said "current code", I meant the DXVK artifact I downloaded from here: https://github.com/doitsujin/dxvk/actions/runs/33633088810

Let me know if that wasn't current code.

@doitsujin

Copy link
Copy Markdown
Owner Author

That is the current iteration of the branch, yeah.

Anyway, guess I'll have to look into that, if it really is 32-bit stuff that's broken then that would be rather unfortunate.

@doitsujin

Copy link
Copy Markdown
Owner Author

Yeah, it's broken due to winevulkan unfortunately. Just looked at the code and the 32-bit struct conversion leaves a few things undefined that cause the driver to do weird things, including segfaults and the VK_INCOMPLETE issue you ran into.

Doesn't look like an easy fix either, pain.

@doitsujin
doitsujin force-pushed the present-timing-v2 branch 2 times, most recently from 2a6380f to 73d623c Compare September 4, 2026 08:46
@doitsujin

Copy link
Copy Markdown
Owner Author

32-bit woes should be fixed as of https://gitlab.winehq.org/wine/wine/-/merge_requests/11862.

There's no great way to detect a "good" wine build at runtime, so on wine builds without that patch it'll just crash or otherwise misbehave. That problem should solve itself over time.

@bigjoe54321

Copy link
Copy Markdown

Thanks for that good news and the work you've done.

The 32/64-bit games I tested all work now with that Wine PR merged into this Proton build, which has your latest present timing DXVK changes in it:
https://github.com/NelloKudo/proton-dev/actions/runs/33871680219/artifacts/9940066316
For anyone who wants to use present timing with that build I linked, you have to use these environment variables:
PROTON_PRESENT_TIMING=1 PROTON_ENABLE_WAYLAND=1

Repeating Frame Time Spikes

I discovered this bug that happens in every 32/64-bit game I tested, even without that Proton build linked above.

As far as I've seen, the repeating frame time spikes happen only with your latest present timing DXVK files, regardless of whether I use the linked Proton build or proton-cachyos-slr. With dxvk.enablePresentTiming = False, the bug does not happen in any games I tested with the linked Proton build.

Another important thing to know is that I don't see the game stuttering/jittering/freezing when I move my mouse in the games I tested. The only reason I know about this bug is the fact that those frame time spikes appear in DXVK HUD and MangoHud; see the screenshots of the frame time graphs for context.

dxvk.enablePresentTiming = False in dxvk.conf

Screenshot_20260904_103839

hl2_d3d9 dxvk.enablePresentTiming = False.log
steam-1583720 dxvk.enablePresentTiming = False.tar.gz

# dxvk.enablePresentTiming = True in dxvk.conf

Screenshot_20260904_093542

hl2_d3d9.log
steam-1583720.tar.gz

@doitsujin

doitsujin commented Sep 4, 2026

Copy link
Copy Markdown
Owner Author

Doesn't really sound actionable unless i find a way to reproduce that manually. Neither the HUD nor Mangohud show what's actually happening at a compositor level, but 13ms is multiple frames, that shouldn't happen.

Are you benchmarking this with validation layers enabled? If so then you really want to turn those off, they're not exactly free.

We're periodically re-calibrating timestamps because apparently some AMD hardware has bugged clocks, could be that too, but yeah would need a way to actually repro this. So far I haven't seen it even on my Nvidia card.

(also, for the record, DXVK_LOG_LEVEL=debug isn't super useful here, it just adds some unrelated noise)

@bigjoe54321

bigjoe54321 commented Sep 4, 2026

Copy link
Copy Markdown

Are you benchmarking this with validation layers enabled? If so then you really want to turn those off, they're not exactly free.

Yes, I think I did have those enabled. These are some of the env vars in my games' launch options.
VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation DXVK_DEBUG=validation DXVK_LOG_LEVEL=debug PROTON_LOG=1

(also, for the record, DXVK_LOG_LEVEL=debug isn't super useful here, it just adds some unrelated noise)

I'll change the above options to this, most likely. I might do some tests with these.
DXVK_LOG_LEVEL=info PROTON_LOG=1

We're periodically re-calibrating timestamps because apparently some AMD hardware has bugged clocks, could be that too, but yeah would need a way to actually repro this. So far I haven't seen it even on my Nvidia card.

EDIT: I'm using a Ryzen 7 5800X and NVIDIA GeForce RTX 3070. I don't know if either of those is the cause of the bug.

It could be the KWin build I'm using, which, on my device with KDE Plasma 6.7.4, can be built and installed for CachyOS (and probably for other distros based on Arch Linux, too) with these commands. Your (anyone reading this) results may vary; be prepared for any possible crashes or data loss (BTRFS snapshots can be helpful here).

git clone https://invent.kde.org/erhanbilgili/kwin.git
cd kwin/
git checkout commit-timing-6-7-kdeonly
cd package/arch/
makepkg -si

@bigjoe54321

bigjoe54321 commented Sep 4, 2026

Copy link
Copy Markdown

I did a test without using any game launch options in Steam. The same bug still happens. I still have DXVK's FPS limiter set to 140 in my environment.d file. I'll comment it out or set it to -1, log out, log in again, and try another test.

EDIT: I had to reboot to get the DXVK FPS limiter to disappear from env | rg -S dxvk.

image

@bigjoe54321

bigjoe54321 commented Sep 4, 2026

Copy link
Copy Markdown

Something's still limiting my FPS to about 140 while I'm at the main menu, and I am not using the in-game FPS limiter. I doubt it's the DXVK_FRAME_PACE=low-latency-vrr-144 or PROTON_DXVK_LOWLATENCY=1 in my environment.d file, but I'll disable those one by one to see what happens.

EDIT: And the bug was still happening just before I wrote this post.

@doitsujin

Copy link
Copy Markdown
Owner Author

Well, all I can say right now is that I can't reproduce it, far too many variables at play here (Proton builds, compositors, games, etc).

@bigjoe54321

Copy link
Copy Markdown

It was the dxvk.maxFrameRate = 140 in my dxvk.conf. I'm about to find out if I'm correct...yeah, I was correct. Also, the bug is now gone. All it took was disabling the DXVK FPS limiter.

image

@doitsujin

Copy link
Copy Markdown
Owner Author

Well, disabling the limiter also disables present timing.

@doitsujin

Copy link
Copy Markdown
Owner Author

Maybe try reverting 73d623c in your build. We can't detect VRR currently (wayland protocol issue), but if that commit is the problem somehow then something must be really wrong with clock sources on your setup.

@bigjoe54321

Copy link
Copy Markdown

Well, disabling the limiter also disables present timing.

This log shows present timing still working without your FPS limiter, and there's still no bug anymore. I might be reading the log wrong, though.

I'm at about 144 FPS in game now, which is my max monitor refresh rate. VRR is enabled. I did not revert the commit yet; this is the same Proton and DXVK versions as the last few tests.
hl2_d3d9.log

@doitsujin

doitsujin commented Sep 4, 2026

Copy link
Copy Markdown
Owner Author

Well it doesn't really do anything useful if you're running at the maximum possible refresh rate anyway. The fact that it's not disabled in this scenario is a bug, and the only thing it's going to do is cause problems.

Guess it's because of this:

Presenter: Unable to determine display refresh rate

Need to come up with something here I guess. We literally cannot know the refresh rate or whether VRR is annoying, even though the VUlkan extension is supposed to give us that info and we kind of need it to make useful decisions.

@bigjoe54321

Copy link
Copy Markdown

TL;DR is that this kicks in if

  • VSync is enabled with a sync interval > 1 or with a "fake" display mode (e.g. 60 Hz on 144 Hz display), or
  • The built-in frame rate limiter is used.

Does this mean VSync and the DXVK frame rate limiter must both be enabled at the same time? I'm asking because I'm confused by the "or" at the end of the first bulleted line.

@doitsujin

Copy link
Copy Markdown
Owner Author

Vsync is always required, yes.

The first bullet point is about us emulating non-native refresh rates. We can't modeset on wayland, so we have to use our own FPS limiter to actually ensure that games requesting 60 Hz modes run at 60 Hz or all hell breaks loose, and now present timing basically does that.

@doitsujin

doitsujin commented Sep 4, 2026

Copy link
Copy Markdown
Owner Author

I don't want to add more heuristics here either. The FPS limiter already only kicks in if we're actually running faster than the requested frame rate for a brief period of time, but that's not really viable here because we really want present timing active for games that have a built-in FPS limtier but don't change the display mode.

This entire situation sucks, sigh. Gonna ignore this for now, but if setups continue to a) not report refresh rate and b) not report VRR enablement, we'll potentially be wasting a lot of power on busy-waiting to pace the app thread when timing is enabled. Which means we can't enable it by default because it's just going to drain e.g. Steam Deck battery for literally no reason.

@doitsujin
doitsujin force-pushed the present-timing-v2 branch 2 times, most recently from cc3520a to 526a735 Compare September 4, 2026 19:18
@bigjoe54321

Copy link
Copy Markdown

#5869 (comment)

I'll wait until KDE 6.8 Beta 1 releases in the kde-unstable Arch Linux repo. If commit timing works in beta 1, beta 2, or the stable 6.8 release, then I might report what the frame times and VRR are doing on my device.

See the beta release dates in the link below.
https://community.kde.org/Schedules/Plasma_6#Future_releases

@doitsujin

doitsujin commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

The log doesn't show "info: Presenter: Absolute timing enabled (75.0 FPS)" like the other games do.

Like I said earlier, it doesn't do anything useful if the timing interval matches your refresh rate so we won't enable it in that case if we actually know the refresh rate. The other games also mostly disable it as soon as the refresh rate is known, as can be seen in the log.

Splinter Cell is a case where it's working as intended though:

info:  Presenter: Reported refresh rate: 74.9 Hz 
info:  Presenter: Absolute timing enabled (60.0 FPS)

@danielfikko

danielfikko commented Sep 5, 2026

Copy link
Copy Markdown

Now I understand. So all the games I have installed, with the exception of Splinter Cell 1 and 2, don't need this MR, since the refresh rates match in the output log. Thank you for the explanation!

EDIT: I thought this PR was intended to "fix" vsync on linux, especially on wayland. I followed the discussions on the wayland protocols commit-timing-v1 and fifo-v1, which had exactly that intention. And well, vsync is essentially about synchronizing the game’s refresh rate with that of the display, so I thought that the fact that Reported refresh rate: 74.9 Hz and Presenter: Absolute timing enabled (75.0 FPS) matched up was exactly what was expected and could be considered working. Sorry for the noise!

@DarkSwan86

Copy link
Copy Markdown

Quick update: Kwin has merged the commit timing protocol!

@doitsujin

Copy link
Copy Markdown
Owner Author

Cool, sounds like 6.8 will include it?

Guess the biggest issue now is that XWayland doesn't really support a useful feature set. On Mesa it can handle the SyncInterval > 1 case (i.e. running at half refresh), but not e.g. 60 FPS on 144 Hz display because it lacks absolute timing support and doesn't report VRR either.

@DarkSwan86

DarkSwan86 commented Sep 8, 2026

Copy link
Copy Markdown

Cool, sounds like 6.8 will include it?

Guess the biggest issue now is that XWayland doesn't really support a useful feature set. On Mesa it can handle the SyncInterval > 1 case (i.e. running at half refresh), but not e.g. 60 FPS on 144 Hz display because it lacks absolute timing support and doesn't report VRR either.

I think yes indeed because the branchpoint for Plasma 6.8 is Thu 2026-09-10.

@doitsujin

Copy link
Copy Markdown
Owner Author

Turns out there was a bug with relative timing, the Windows/XWL use cases that this covers should work more consistently now.

@bigjoe54321

bigjoe54321 commented Sep 9, 2026

Copy link
Copy Markdown

Is it normal for the input latency to increase when present timing is active in D3D9 and D3D11 games? It feels that way, but I don't have a way to prove it with measurements.

I don't have NVIDIA LDAT or similar hardware to measure the latency I'm sensing in games. I can't measure latency with pyrofling, either, because If I load pyrofling's latency measurement layer, which uses present timing, then DXVK's present timing won't work, according to the DXVK logs.

When I disable present timing in dxvk.conf, the latency in game feels lower than before I disabled it.

  • DXVK build: Latest. Commit 669f1b4. The increased latency is also felt in older builds on my PC.
  • Compositor: Jay (it has commit timing)
  • Present mode: FIFO
  • VRR: Enabled
  • VSync: Enabled
  • Proton: https://github.com/nanomatters/proton-cachyos/releases/tag/wineland-11.0-20260908
  • PROTON_ENABLE_WAYLAND=1
  • DXVK FPS limit: 142. No in-game FPS limit
  • Monitor refresh rate: 144
  • GPU: NVIDIA GeForce RTX 3070 with proprietary driver 610.57.04. There's no iGPU in this PC
  • CPU: AMD Ryzen 7 5800X

@doitsujin

doitsujin commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

tldr yes, normal. There is no universe where you can get both consistent timing and lowest possible input latency without the game supporting Reflex and friends.

Edit: You can generally mitigate this somewhat by setting dxgi.maxFrameLatency=1 or the D3D9 equivalent.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants