I’m happy to say that with tips in this thread, a CRT, and a heap of stubbornness, I’ve achieved real provable next-frame response time — sub-16ms lag!

First, my testing procedure:

RetroArch on Linux in KMS mode

CRT (Sony Trinitron)

iPhone with 240fps slow-mo video capture

Here’s a simple video showing my methodology and results: https://www.youtube.com/watch?v=lBwLSPbHWoc

What’s great about using a CRT for these slow-mo tests is you can see the scanline move down the tube, and know exactly when a frame begins and ends. No need for fractional frame analysis and averaging. At 240fps, you get four captured frames per TV frame. Obviously, the faster slow-mo camera you have, the better. But iPhones and other smartphones do just nicely.

Like @Brunnis said (at some point), it’s unnecessary to hack together wires and LEDs to controllers for personal testing. Deliberately/flamboyantly pressing a button on the controller while simply holding it front of the TV is enough. At 240fps, there’s only about a single slow-mo video frame (or 4ms) of ambiguity as to whether a button is hit or not.

I’ve always used Super Mario Bros. on the NES as my casual lag litmus test, and let my muscle memory be the judge. It seemed logical to use for my slow-mo tests too. I have a real NES (well, an AV-modded Famicom) for comparison using the same CRT.

Early in the process, I discovered two things:

1: On real hardware, Mario has a one-frame lag! I feel completely betrayed all these years having never known this! The soonest you’ll see an input response (jumping, etc) is greater than 16ms after your input.

2: RetroArch’s Nestopia core seems to have an additional frame of lag unaccounted for, bringing the total minimum lag for a Mario jump to over 32ms. QuickNES does not have this additional frame of lag.

With these two findings, I decided to find another game to test. I chose Pitfall! for the Atari 2600, using the Stella core.

With Pitfall, I witnessed a response on the very next frame. In the video linked above, you can clearly see me hit the button near the end of one frame, and on the next, Harry jumps! Essentially no way to improve compared to original hardware. Pack it up. We’re done here

This method of testing has worked really well for me, and was not very difficult at all. With a video app that allows for frame-by-frame movement (on macOS, I just use QuickTime Player), counting frames is easy. A CRT is of course not required, but watching the beam race down the tube lets you know exactly when a new frame is coming. And hopefully armed with the knowledge that Stella can react with zero lag can help others test their own equipment much easier.

Eliminating lag has been a crusade of mine for years. It had been distracting enough that merely enjoying old games was nearly impossible. Maybe now I can play my old games without “worry”.

Extra stuff:

There’s been talk about digital-to-analog converters (HDMI to VGA, or DP to VGA) being a source of display lag. Yeah sure, if you want to be pedantic (we all do), every signal transformation TECHNICALLY produces additional lag, but in most cases, the lag is beyond minuscule. Less than a single millisecond. Think about it: There’s not much hardware in most cheap converters. Each and every frame of 1080p video contains over 2MB of data. If the adapter has sizable lag, where is it going to PUT those frames it’s supposedly holding onto?

Full specs:

CPU: i5-5675C

Graphics: Intel Iris 6200

OS: Ubuntu 17.04

Latest RetroArch Nightly

Display: Random DisplayPort to VGA adapter

Extron VSC 500 (not required, but makes my VGA 240p signal look nicer)

VGA to circuit feeding CRT jungle chip

Sony Trinitron TV

Linux Settings:

Custom 1920x240p EDID via DisplayPort

RetroArch launched in KVM mode through basic command-line (not GUI)

Linux RetroArch settings:

VSync On

Maximum Swapchain Images: 2

Frame Delay: as high as you can go without stuttering. 15 works for me for 8-bit systems

Integer Scaling

No filters

Input device: Super Famicom controller

Dual SNES controller to USB adapter - V2, configured to 1ms of lag. Website specs say 2ms minimum, but hey, 1ms was an option in the controls, and Linux reports 1ms poll time…