blurbusters / RefreshRateCalculator

Apache License 2.0
8 stars 0 forks source link

Add a raster estimator method (beam racing, raster interrupt style) #1

Open mdrejhon opened 1 year ago

mdrejhon commented 1 year ago

Raster estimator is possible with VSYNC timestamps.

// Run this after a 10-second refresh cycle counting initialization at startup (but keep counting beyond, to incrementally improve accuracy sufficiently enough for beam racing apps)
var accurateRefreshRate = hertz.getCurrentFrequency();
var scanoutPercentage = hertz.getRasterScanoutPercentage();

// Common VBI size for maximum raster accuracy, adjust as needed.  VGA 480p has 45, and HDTV 1080p has 45
// Or optionally use #ifdef type for plat-specific APIs like Linux modelines or Windows QueryDisplayConfig()
var blanking = 45;   

// Vertical screen resolution
var height = screen.height;

// Signal vertical total.  You could ignore blanking, with a bit more error margin 
// (fine for frameslice beamracing for emulators, ala WinUAE lagless sync, but in a more crossplatform way)
var verticalTotal = height + blanking;

// Estimated current raster scan line number at this instant on the GPU output, assuming portrait-mode display
var raster = scanoutPercentage * verticalTotal;

//   OPTIONAL: If your VSYNC timestamp is end-of-VBI rather than start-of-VBI, then compensate
//     However, most frame presentation APIs (running at max rate) unblock at end of refresh cycle (beginning of VBI)
// raster += blanking
// raster = (raster % verticaltotal);

While you can guesstimate the raster during javascript, you can't do any rasterdemos because you can't use VSYNC OFF + high framerates in a web browser outside requestAnimationFrame(). But this generic math code is highly portable to other languages.

mdrejhon commented 1 year ago

Setting up Google Chrome for high performance VSYNC OFF

Breakthrough: You can beam race VSYNC OFF tearline position in a web browser! These instructions are a prelude to beam racing.

Incidentally, it is possible to run Chrome in VSYNC OFF mode, so it is actually possible to beamrace in a web browser! A bit unwieldly, but it works on modern powerful GPUs!

One needs to run two separate instances of Chrome -- one in VSYNC ON mode (to get the refresh rate heartbeat) and another in VSYNC OFF mode (for beamracing tearlines or 'lagless vsync' algorithms in a browser emulator, like WinUAE). A WebSocket can communciate a VSYNC heartbeat from the VSYNC ON instance to the VSYNC OFF instance on the same computer (under Windows).

  1. Close all browsers and applications.
  2. Quit any background software that generates CPU spikes (e.g. Dropbox, RGB-controller software, Razer Synapse, etc)
  3. Make sure NVIDIA Control Panel -> Manage 3D Settings -> Global Settings is configured with the following: | "Vertical sync" = "Use Application Setting" | "Power management mode" = "Prefer maximum performance"
  4. Create a desktop shortcut with this:

"C:\Program Files\Google\Chrome\Application\chrome" --user-data-dir=c:\windows\temp\vsync-off --disable-gpu-vsync --disable-frame-rate-limit https://testufo.com/blurtrail#thickness=8&ppf=8

"C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe" -lgc 1710

If you don't have nvidia-smi.exe, download the latest NVIDIA drivers again, then open the driver .EXE in 7-zip (it's a self extracting EXE, don't need to reinstall drivers), and copy nvidia-smi.exe out of it. Note, you will need to reboot to undo the clock-locking done by nvidia-smi.exe

if you setup correctly, you will see massive tearing in the vertical moving line, and ultra high frame rates:

TestUFO Tearing

mdrejhon commented 1 year ago

Beam racing works in Chrome only, not FireFox (for now)

Tried to test FireFox, it doesn't work like it does in Chrome; Tried to force a few about:config settings in FireFox.

I get higher frame rates in FireFox, but only about 2-3x frame rate over refresh rate, and no tearing appears.

Spinoff Usefulnesses Beyond Browsers

I simply do the audacity of beamracing in a web browser as a stupidly-HLE that nobody believes can do beam racing. It's just to showoff that lesser languages are capable of beam racing usefulnesses (e.g. WinUAE's Lagless VSYNC mode).

Here is the Lagless VSYNC algorithm that is implemented by WinUAE, but could actually be ported to other emulators in a more cross-platform manner, with the help of the algorithms in RefreshRateCalculator.js

mdrejhon commented 1 year ago

Raster estimator has been added. Meanwhile, copying and pasting from another forum (for myself and others):

Possible sources of refresh cycle heartbeats (signal VSYNC)

VSYNC heartbeats can be obtained from multiple sources, as follows:

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.

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!