bgfx
bgfx copied to clipboard
Add support for exclusive fullscreen mode
I'm currently developing a game using bgfx as the renderer, targeting for desktop platforms (Windows/Linux/OS X). The game is a rhythm game, where lowest possible latency is desired in both audio and video fronts.
By having proper support for exclusive fullscreen mode (when available), video latency can be reduced to minimum in some various setups. Here is a list of scenarios gathered from over the internet and some backed by my personal experience:
- Windows (Vista/7) are known for having slight delays (+1 frame) when rendering games in windowed modes, which can be remedied with various hacks like disabling the desktop composition (DWM).
- Windows (8.x/10): Desktop composition can no longer be disabled in these versions. I haven't personally noticed any display delay in these versions, but there are some users who still claims to have noticeable difference between windowed and exclusive fullscreen modes.
- Optimus Laptops: The latency in these devices may come from the bridge between Intel and Nvidia GPUs. Basically the Intel GPU is always active and is responsible for rendering the desktop, and when the discrete GPU is activated, the framebuffer content is bridged over to Intel GPU to display it. I am not sure if this still applies when a game is run in exclusive fullscreen mode, but I am noticing less stuttering in fullscreen even though the reported framerates are very high.
TL;DR: There is still some demand for having exclusive fullscreen mode available for video games, especially in games where low latency is highly desired.
I've heard OpenGL has very poor if no support at all for exclusive mode in some platforms/drivers. Would it be possible to add support for BGFX_RESET_FULLSCREEN in the backends where it can be implemented fairly easily, ignoring the flag when it's not supported?
If I understood correctly, the flip model presentation introduced in D3D9Ex and D3D11.1 provides the same benefits than the exclusive fullscreen mode, which effectively bypasses the DWM completely and renders the back buffer content immediately to the display.
It seems that bgfx already uses the flip model in D3D11 and D3D12 backends (but not in D3D9, unsure about OpenGL), so the need for exclusive fullscreen mode isn't that critical anymore. This of course applies to Windows 7+ platforms only, I have no idea if the latency is an issue in Linux/OS X.
:+1: from me... I'm also facing latency woes here, I've tried running single-threaded but overall throughput drops and imho the cost of 1 frame latency for internal buffering is acceptable so I'm OK with that, but exclusive fullscreen seems to be a great way to reduce latency without performance drawbacks. In my case it's the FPS camera that gets unresponsive (input lag), 2 extra frames on top of whatever the GPU driver is adding is just too much for my taste, if framerate drops below 40fps it gets very uncomfortable.
+1 on this. I've been looking to move to bgfx from bare opengl, and this is a huge deal breaker.
I was initially hopeful with the new DXGI "allow tearing" flag, but after reading more about it and testing it, it really doesn't do what it says it does at all, it's just for VRR displays (which don't have tearing by definition), and the functionality is not supported on regular displays. So that leaves fullscreen exclusive mode as the only remaining option if you want instant buffer flips with tearing, at least on Windows.
Hope it makes it in soon!
https://devblogs.microsoft.com/directx/dxgi-flip-model/ Microsoft seems to specifically claim otherwise. With that (if you have DXGI 1.5 and flip mode) "sync interval 0" should be doable. But maybe that flag is only abided if they actually detect the right monitor.
Check their samples perhaps.
Microsoft seems to specifically claim otherwise.
What I meant is that the constant name is misleading. Considering what it does and requires, it should have been called DXGI_FEATURE_PRESENT_VARIABLE_REFRESH or something similar. Tearing has nothing to do with it.
With BGFX_RESET_NONE and a borderless fullscreen window, I get a forced vsync, even though renderer_d3d11.cpp is using DXGI_SWAP_EFFECT_FLIP_DISCARD like your linked article suggests. PresentMon says it is using "Independent Flip" and "60 fps displayed". Looks like we are stuck in a nightmare timeline where vsync is forced everywhere except exclusive fullscreen mode.
So.. It seems like you also have to pass DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING in two additional places other than just swapchain creation.