Raster "Interrupts" / Beam Racing on GeForces/Radeons!

Talk to software developers and aspiring geeks. Programming tips. Improve motion fluidity. Reduce input lag. Come Present() yourself!
User avatar
Chief Blur Buster
Site Admin
Posts: 11647
Joined: 05 Dec 2013, 15:44
Location: Toronto / Hamilton, Ontario, Canada
Contact:

Re: Raster "Interrupts" / Beam Racing on GeForces/Radeons!

Post by Chief Blur Buster » 10 Feb 2023, 15:47

ad8e wrote:
10 Feb 2023, 12:57
https://github.com/glfw/glfw/issues/115 ... 1425520901 found someone getting sync events on Linux. I haven't yet tried it myself.
Excellent to hear, thanks for posting!

MUCH APPRECIATED -- this is info useful to Blur Busters
Head of Blur Busters - BlurBusters.com | TestUFO.com | Follow @BlurBusters on Twitter

Image
Forum Rules wrote:  1. Rule #1: Be Nice. This is published forum rule #1. Even To Newbies & People You Disagree With!
  2. Please report rule violations If you see a post that violates forum rules, then report the post.
  3. ALWAYS respect indie testers here. See how indies are bootstrapping Blur Busters research!

ad8e
Posts: 68
Joined: 18 Sep 2018, 00:29

Re: Raster "Interrupts" / Beam Racing on GeForces/Radeons!

Post by ad8e » 10 Feb 2023, 21:56

I'll continue the github conversation here, since I'd like to avoid polluting glfw's bug tracker.

What I mean by "inconsistent across platforms" is that the setup function needs to be called in different places, and the per-vsync function might need to be in a different thread or not, and the information you get out of it needs to be handled differently all the time. GLFW is meant to abstract platform differences away, and it cannot do that for vsync timing, so vsync timing does not belong in GLFW. However, GLFW also exposes all the native APIs you need, so it doesn't get in your way.

My CPU is the i5-1240P, which comes with Intel Iris Xe Graphics G7, whose neighbors are the NVIDIA GeForce GTX 675M and AMD Radeon RX 540. I don't have a serious GPU.

On my 2560x1440 monitor in Linux, I get a tearline, but it jumps around between temporarily-stable points. This may be an issue with my code that I can fix. This is a more powerful GPU than my old GPU, but also driving a much larger screen. The tearlines are very coarse at uncapped framerate; I guess my GPU takes a while to paint the whole 2560x1440 screen. The tearline animation which looked cool on my old Windows system looks utterly lame with these coarse tearlines. It doesn't have the 8 px quantum of my old Windows system; I think that quantum is what made it look awesome.

On my laptop's builtin 2256x1504 monitor in Linux, I am not able to tear at all. Same code, same system, just different screen.

I still have my old 1366x768 Windows laptop, and everything still works there. I probably have access to a few more Windows computers with integrated graphics and various monitors.

grieverheart
Posts: 1
Joined: 04 Aug 2023, 04:03

Re: Raster "Interrupts" / Beam Racing on GeForces/Radeons!

Post by grieverheart » 04 Aug 2023, 07:44

So, if I understand correctly, there will always be an input latency of somewhere between 0 and 1 frame. This is because we need to wait for the "beam" to reach the correct position before we swap/present. In emulation you can just pause the emulation until this is achieved, so the input lag is reduced to just a frame slice, but what if you have an input source you want to present? Is there a way to e.g. reset the beam position so as to minimise the difference between the input and the desired output raster positions?

Also, I think it's been a few years since you first posted the method. Have you perhaps released the source code you mentioned before? You say it's cross-platform, but I'm not sure how you acquire the vsync timestamps on the different platforms like Linux and MacOS.

User avatar
Chief Blur Buster
Site Admin
Posts: 11647
Joined: 05 Dec 2013, 15:44
Location: Toronto / Hamilton, Ontario, Canada
Contact:

Re: Raster "Interrupts" / Beam Racing on GeForces/Radeons!

Post by Chief Blur Buster » 10 Aug 2023, 15:27

grieverheart wrote:
04 Aug 2023, 07:44
So, if I understand correctly, there will always be an input latency of somewhere between 0 and 1 frame. This is because we need to wait for the "beam" to reach the correct position before we swap/present. In emulation you can just pause the emulation until this is achieved, so the input lag is reduced to just a frame slice, but what if you have an input source you want to present? Is there a way to e.g. reset the beam position so as to minimise the difference between the input and the desired output raster positions?
No you cannot reset a raster*

*Except on VRR displays, where if the display is idling, the next frame presentation event starts the raster incrementing immediately, only if the display was idling. But once it starts refreshing, it scans out at a constant speed based on horizontal scanrate. Once it's scanning out, you can beamrace it. (WinUAE Lagless VSYNC can beamrace VRR refresh cycles too!).

For traditional render you have to use techniques like SpecialK or RTSS Scanline Sync to hide the VSYNC OFF tearline. Delay your input read until as close as possible to rendertime/displaytime, so that the freshest control is displayed.

grieverheart wrote:
04 Aug 2023, 07:44
Also, I think it's been a few years since you first posted the method. Have you perhaps released the source code you mentioned before? You say it's cross-platform, but I'm not sure how you acquire the vsync timestamps on the different platforms like Linux and MacOS.
I'm releasing piecemeal for now -- there's a new VSYNC dejitterer with a raster estimator here:
https://github.com/blurbusters/RefreshRateCalculator

Possible APIs to get timestamps:
https://github.com/blurbusters/RefreshR ... 1651063875

In Linux best one to use is XRRGetCrtcInfo() which returns the XRRCrtcInfoSource which includes a timestamp.
In MacOS/iOS it is the CADisplayLink or CVDisplayLink APIs.

But you have to use the VSYNC OFF mode to eliminate the tearlines. One way to do things is to temporarily use VSYNC ON at startup to get the time interval, then switch to VSYNC OFF. A roughly 30 second startup calibration (dejittered with RefreshRateCalculator.js) tends to deadreckon/extrapolate accurately for about 30 minutes thereafter.

ad8e managed to find the Linux VSYNC listener and beamrace tearlines on Linux with this github project:
https://github.com/ad8e/vsync_blurbusters
(It compiles under Windows and Linux, with a stationary VSYNC OFF tearline capability)
For the Linux #ifdef, it uses the xrandr XRRCrtcInfoSource.

Some operating systems (Windows 11) lets me do VSYNC ON and VSYNC OFF simultaneously in separate windows, and the VSYNC ON window can stream timestamps to the VSYNC OFF context, and the dejitterer can undo any API-overhead/RPC/async jitter caused.

P.S. I recently got Kefrens Bars working in a Google Chrome window in VSYNC OFF mode! I have not released the URL because it requires custom browser command line for the VSYNC OFF, and I haven't implemented the websocket relay yet. Not possible to screenshot it, so it's true-raster-beamraced. Needs a websocket relay between a VSYNC ON profile and a VSYNC OFF profile.

This is currently an unpaid hobby side project, so I haven't done much work in this territory lately; however, I'd love to help someone start an open source VSYNC listener with a bunch of #ifdef's for different platforms. A VSYNC timestamps daemon, if you will. I'd throw in some code contributions perhaps. Might require access to specific driver registers / etc on certain platforms, while APIs already exists on other.

Do you want to help create a new MIT / Apache 2.0 project that is kind of a cross platform VSYNC daemon?

There is a chicken and egg problem
- Modern GPU programmers don't understand rasters
- Old fashioned programmers don't understand modern GPU programming

So, it's been hard to get volunteers to help out with such hobby projects.
Head of Blur Busters - BlurBusters.com | TestUFO.com | Follow @BlurBusters on Twitter

Image
Forum Rules wrote:  1. Rule #1: Be Nice. This is published forum rule #1. Even To Newbies & People You Disagree With!
  2. Please report rule violations If you see a post that violates forum rules, then report the post.
  3. ALWAYS respect indie testers here. See how indies are bootstrapping Blur Busters research!

User avatar
Chief Blur Buster
Site Admin
Posts: 11647
Joined: 05 Dec 2013, 15:44
Location: Toronto / Hamilton, Ontario, Canada
Contact:

Re: Raster "Interrupts" / Beam Racing on GeForces/Radeons!

Post by Chief Blur Buster » 10 Aug 2023, 16:11

For those interested in finding VSYNC timestamps, I've collected all the info in one convenience place for anyone who wants to help create a cross-platform VSYNC timestamps daemon...

Possible sources of refresh cycle heartbeats (signal VSYNC)

VSYNC heartbeats can be obtained from multiple sources, as follows:
  • Generic Method: (Does not always work), Create a VSYNC ON window and a VSYNC OFF window, if your framework allows creating multiple separate VSYNC configurations in different contexts (separate apps / thread / process). Communicate the VSYNC timestamps from VSYNC ON context to the VSYNC OFF context.
  • Microsoft documentation on waitable swapchains
  • C# XBox/MonoGame: Update()+Draw() generally tries to tick to VSYNC during VSYNC ON
  • DirectX: Timestamping the exit from max-framerate Present() (exit from blocking behavior = timestamp of VSYNC). But try to use waitable swapchains instead to reduce lag!
  • OpenGL: Timestamping the exit from max-framerate glFinish/glSwapBuffers for blocking behaviors (exit from blocking behavior = timestamp of VSYNC). (See above, though)
  • Javascript/HTML5: requestAnimationFrame() generally tries to tick to VSYNC during VSYNC ON
  • Windows Compositor Clock (which may vary, e.g. battery management)
  • Alternatively, there's sidechannel APIs to find timestamps from GPU's VSYNC:
    .....Windows: D3DKMTWaitForVerticalBlankEvent()
    You don't have to use D3D for the rest, still works in a headless app! And independently during OpenGL or Vulkan.
    .....Android: SurfaceFlinger callback
    .....MacOS/iOS: CADisplayLink or CVDisplayLink
    .....Linux: XRRGetCrtcInfo (xrandr)
    Remember that not all window managers are vsync'd, but kwin-lowlatency fork did a fantastic job and its work is now upstream in a few window managers
The sidechannel methods are the best for a background library / daemon. Keep in mind certain GPUs (e.g. M2/M3) do not currently seem to let you do any tearing (even though you can still do latency reduction tricks from knowing VSYNC timestamps). But it works on Intel/AMD/NVIDIA GPUs just fine, including Intel/AMD on Macs.

For true beamracing tricks, it is a conundrum -- needing both VSYNC ON and VSYNC OFF for different reasons. Beam racing can only be done in VSYNC OFF mode, but successful VSYNC timestamps are easier with VSYNC ON. So as long as the problem is solvable one way or another (via small hooks via platform-specific #ifdef-ing), you can beamrace tearlines on any platform!

Help appreciated creating a cross-platform VSYNC daemon/library

This would make releasing a lot of my Tearline Jedi source code so much easier, because I don't have continuous access to all the platforms needed for all the testing. However, as you can see, snippets and due diligence is available!
Head of Blur Busters - BlurBusters.com | TestUFO.com | Follow @BlurBusters on Twitter

Image
Forum Rules wrote:  1. Rule #1: Be Nice. This is published forum rule #1. Even To Newbies & People You Disagree With!
  2. Please report rule violations If you see a post that violates forum rules, then report the post.
  3. ALWAYS respect indie testers here. See how indies are bootstrapping Blur Busters research!

Pyrolistical
Posts: 2
Joined: 27 Jan 2024, 18:50

Re: Raster "Interrupts" / Beam Racing on GeForces/Radeons!

Post by Pyrolistical » 27 Jan 2024, 18:58

Interesting stuff. Is my understanding correct when vsync is off?
  1. You don't need to clear the front buffer, you only add more rows per slice.
  2. [s]When present() is called the entire front buffer is sent down the wire to the display.[/s]
  3. When present() is called your front buffer is copied to the gfx internal buffer, which is what is being streamed over the display cable.
[s]If 2. is true, then is time being wasted? Would this be made more optimal if api/video cards/display port standard could allow present(starting_from_row)?[s]

edit: the more I think about it, the video card can continue streaming the front buffer over the wire. it wouldn't resend the whole frame upon present(). the display shouldn't buffer anyways

User avatar
RealNC
Site Admin
Posts: 3741
Joined: 24 Dec 2013, 18:32
Contact:

Re: Raster "Interrupts" / Beam Racing on GeForces/Radeons!

Post by RealNC » 28 Jan 2024, 20:23

Pyrolistical wrote:
27 Jan 2024, 18:58
edit: the more I think about it, the video card can continue streaming the front buffer over the wire. it wouldn't resend the whole frame upon present(). the display shouldn't buffer anyways
That's indeed how it works. This is also the source of tearing. Every change you make to the front buffer means the signal will simply contain that new data from the current scanout position onwards. The already scanned out pixels are still there and won't be updated until the scanout wraps around again to the beginning of the front buffer.
SteamGitHubStack Overflow
The views and opinions expressed in my posts are my own and do not necessarily reflect the official policy or position of Blur Busters.

User avatar
Chief Blur Buster
Site Admin
Posts: 11647
Joined: 05 Dec 2013, 15:44
Location: Toronto / Hamilton, Ontario, Canada
Contact:

Re: Raster "Interrupts" / Beam Racing on GeForces/Radeons!

Post by Chief Blur Buster » 04 Feb 2024, 16:24

Pyrolistical wrote:
27 Jan 2024, 18:58
edit: the more I think about it, the video card can continue streaming the front buffer over the wire. it wouldn't resend the whole frame upon present(). the display shouldn't buffer anyways
The problem is that when the graphics card is artisting the image, it doesn't draw the scene from top to bottom. It might draw the ground first, or a specific building then that building. The order of graphics draw will never be in sync with the order of display refresh.

Therefore, the graphics card needs to buffer, OR there will be tearing even with the front buffer idea;

However, custom software can be designed to render in a beam-raced manner, but it requires microsecond precision and lots of hacks (like in this thread) to force a graphics card to draw sequentially.
Head of Blur Busters - BlurBusters.com | TestUFO.com | Follow @BlurBusters on Twitter

Image
Forum Rules wrote:  1. Rule #1: Be Nice. This is published forum rule #1. Even To Newbies & People You Disagree With!
  2. Please report rule violations If you see a post that violates forum rules, then report the post.
  3. ALWAYS respect indie testers here. See how indies are bootstrapping Blur Busters research!

Post Reply