Vulkan: Change double buffered VSync to match display without blocking #1012

Open
goeiecool9999 wants to merge 35 commits from goeiecool9999/vsyncoverhaul into main
goeiecool9999 commented 2023-10-29 16:21:33 -03:00 (Migrated from github.com)

This replaces the Double buffered VSync mode with a mode that tries to match the physical display.
It tracks how fast frames are being presented and takes over signalling vsync if the presentation interval is within 1% of the emulated vsync interval for more than 60 frames. It returns to the fixed emulated timer if it is more than 1% from the desired interval for 60 frames.
Tripple buffered VSync and VSync off use the old method of driving present with SwapBuffers, to allow VRR to reduce stuttering and external tools to see exact frametimes.

How is the match display mode implemented:

  • Decouple the GPU SwapBuffer command from actual presentation.
  • Instead use two vulkan textures as a representation of a front and back buffer and let games only draw to the back buffer.
  • SwapBuffer simply changes which texture gets shown during presentation.
  • AcquireImage doesn't block and simply bails if there is no frame ready yet. GPU thread never blocks on presentation code anymore

Why:

  • Platform neutral way of signalling VSync based on host refresh rate
  • No blocking on GPU thread, more opportunity to do work.

Questions:
It seems that on linux when using the match physical display mode the GPU thread idles a lot. I can't figure out exactly why. vkAcquireNextImage does not block but when I pause the process in a debugger the GPU thread is always in that function waiting for a condition variable. This isn't the case using any of the modes where vkAcquireNextImage is only called at the emulated vsync interval.

This replaces the Double buffered VSync mode with a mode that tries to match the physical display. It tracks how fast frames are being presented and takes over signalling vsync if the presentation interval is within 1% of the emulated vsync interval for more than 60 frames. It returns to the fixed emulated timer if it is more than 1% from the desired interval for 60 frames. Tripple buffered VSync and VSync off use the old method of driving present with SwapBuffers, to allow VRR to reduce stuttering and external tools to see exact frametimes. How is the match display mode implemented: - Decouple the GPU SwapBuffer command from actual presentation. - Instead use two vulkan textures as a representation of a front and back buffer and let games only draw to the back buffer. - SwapBuffer simply changes which texture gets shown during presentation. - AcquireImage doesn't block and simply bails if there is no frame ready yet. GPU thread never blocks on presentation code anymore Why: - Platform neutral way of signalling VSync based on host refresh rate - No blocking on GPU thread, more opportunity to do work. Questions: It seems that on linux when using the match physical display mode the GPU thread idles a lot. I can't figure out exactly why. vkAcquireNextImage does not block but when I pause the process in a debugger the GPU thread is always in that function waiting for a condition variable. This isn't the case using any of the modes where vkAcquireNextImage is only called at the emulated vsync interval.
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin goeiecool9999/vsyncoverhaul:goeiecool9999/vsyncoverhaul
git checkout goeiecool9999/vsyncoverhaul

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git checkout main
git merge --no-ff goeiecool9999/vsyncoverhaul
git checkout goeiecool9999/vsyncoverhaul
git rebase main
git checkout main
git merge --ff-only goeiecool9999/vsyncoverhaul
git checkout goeiecool9999/vsyncoverhaul
git rebase main
git checkout main
git merge --no-ff goeiecool9999/vsyncoverhaul
git checkout main
git merge --squash goeiecool9999/vsyncoverhaul
git checkout main
git merge --ff-only goeiecool9999/vsyncoverhaul
git checkout main
git merge goeiecool9999/vsyncoverhaul
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: cemu-project_Mirror/Cemu-2024-03-05#1012
No description provided.