floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.53k stars 468 forks source link

Turning off Vsync (again) - could it be partially feasible? #1053

Open tmikov opened 1 month ago

tmikov commented 1 month ago

Hi, I know this has already been asked, and I fully appreciate that this is a volunteer library maintained by a single developer (thanks so much for that!!!), so this is in no way a demand, just a gentle question.

How feasible would it be to add no-vsync support to sapp only on some platforms (presumably only the ones that can support it easily)? Is the architecture of sapp even compatible with this? I want try to add this myself, if it is architecturally possible.

Why am I even asking for turning off vsync? Primarily because I need a way to estimate how much headroom I have in my rendering. Sure, I can hit 120Hz on my Mac, but I don't know how close I am to the limit. Am I at risk at falling below 120Hz if I render too many objects? I assume others may be in a similar situation.

I have partially solved this by optionally enabling GLFW as an alternative to Sokol for "benchmarking" mode. However this solution doesn't seem to scale well to other platforms. Plus, with the latest features of Sokol not being supported on Mac+OpenGL, I really have to find an alternative for Metal.

One idea that I have been entertaining is to render additional frames to an off-screen surface between v-syncs, and to count them as real frames, but it will be very tricky and possibly not representative.

floooh commented 1 month ago

If we treat it as a debugging feature until a proper solution arrives, we can just go ahead and implement something that doesn't need to be perfect or supported all platforms (eventually I want to replace the fairly useless sapp_desc.swap_interval thingie with some sort of target framerate hint).

E.g. there could be a sapp_desc.debug_disable_vsync flag and then in the platform-specific setup code there's just minimal if-blocks which do whatever needs to be done to ignore vsync.

The frame-callback architecture of sokol_app.h itself doesn't care, but some platforms (web?) may not easily support calling the frame callback unthrottled. I think it's important though that each frame callback invocation is paired with a platform-specific 'present' call, that present call might just discard the current framebuffer surface.

E.g. I think in DXGI/D3D11 it should be enough to call _sapp_d3d11_present(true) when vsync is disabled (which then calls DXGI Present() with the DXGI_PRESENT_DO_NOT_WAIT flag: https://github.com/floooh/sokol/blob/090d544c5fbfb4ef4f690534950429c89b00fb6f/sokol_app.h#L6613-L6623)

tmikov commented 1 month ago

Great! Yes, I totally view this as a debugging feature.

In that case, I will start by trying to implement debug_disable_vsync for MacOS/OGL, because that's where I have my current setup working with GLFW (showing 2000-4000 FPS đŸ˜…). If that goes well, I can try DirectX next, as you described (I have a Windows PC somewhere, though I am not looking forward to powering it up).