Ok, so I've added v-sync by using QOpenGLWindow and its frameSwapped signal. Some good news and some bad.
V-sync solved one issue. At first with v-sync was still measuring many delays, but I found that some of those were actually measurement errors. QDateTime::currentMSecsSinceEpoch() is not accurate enough, I'm using QElapsedTimer now. Also the code I used to test somehow interfered with the measurement. When I just printed qDebug() << elapsedTimer.elapsed() - lastUpdateRotation; without branch, and did the analysis in excel, I found that almost all frames took 16-17 ms, so exactly 60fps :)
It didn't solve the frame skips on the RTX 2060. I'm getting none on the surface's iGPU (ok, I got a few above 20, but all of these were still below 30ms), but for some reason the desktop with beefy GPU still skips 0.7% of frames. And these are above 40ms, so really noticeable, max is 100ms.
I'm measuring on the frameSwapped signal now, so I can't blame the qt event loop for doing something between frameSwapped and paint. It might be something between the driver and GPU, but I'm still somewhat lost on this part.