|
|
#13 | |
|
Registered User
|
Took a look into Wine 1.1.44 sources. At that times they had been using GLX_SGI_video_sync extension to control vsync and thus been relaying on the different execution branch in nVIDIA driver to achive vsync effect. Thus the bug this topic seems to be a bug in the nVIDIA driver that don't set internal swap_interval counter to be 1 for OpenGL drawables attached to non-fullscreen X11 windows (at least it is how bug manifests itself on my workstation with 280.13 drivers).
|
|
|
|
|
|
|
#14 | |
|
Registered User
|
And another update on topic: looks like currently Wine uses glXSwapIntervalSGI() with an assumption that in case EXT_swap_control is advertised in GLX extension string this function is being implemented as a forward wrapper calling glXSwapIntervalEXT() to do the real work on current active drawable if any. If that's the case then passing zero to glXSwapIntervalSGI() might disable vsync instead of failing with GLX_BAD_VALUE which had been required by SGI_swap_control extension.
Actually EXT_swap_control specs are not explicitly clear on this topic saying "Calling glXSwapIntervalSGI is equivalent to calling glXSwapIntervalEXT on the current drawable, if one exists". It is unclear from this two sentences whether does this "equivalence" mean that glXSwapIntervalSGI() should accept 0 as swap_interval just like glXSwapIntervalEXT() does. It looks like that nVIDIA OpenGL implementation acts just like this. It leads to a fact that if an app sets D3DPRESENT_INTERVAL to be IMMEDIATE it results in glXSwapIntervalSGI(0) call which effectively disables vsync with current nVIDIA drivers. While the behavior isn't clearly documented for nvcontrol "SyncToVBlank" attribute it is clearly stated in docs that setting env variable __GL_SYNC_TO_VBLANK to "1" should force swap_interval to be not less than 1. Driver should be fixed in a way that calls to glXSwapIntervalSGI()/glXSwapIntervalEXT() having swap_interval set to "0" should be silently clamped to use "1" instead (or return with an error - there are no specs available for the "force vsync" case to follow). One wishing to workaround problem for now may try to compile Wine himself after changing one line at dlls/winex11.drv/opengl.c file. It is "else if (!has_swap_control && interval == 0)" condition inside X11DRV_wglSwapIntervalEXT() func that should be changed to "else if (interval == 0)". After this change Wine would not be passing requests to disable vsync to the nVIDIA OpenGL driver. Last edited by lexa2; 10-20-11 at 02:16 AM. Reason: spelling |
|
|
|
|
|
|
#15 | |
|
Registered User
Join Date: Jan 2007
Posts: 119
|
Take a job at nvidia linux department
![]() Quote:
|
|
|
|
|
|
|
#16 | |
|
Registered User
|
Quote:
As for the joke about the job - I'm afraid I'm living a bit far from Taiwan or USA to apply for work position in nVIDIA linux devteam department :-). Also I'm almost inexperienced with linux kernel driver development (had hacked several things here-and-there while been debugging ar71xx ethernet driver bugs in OpenWRT but that doesn't counts) so hiring me wouldn't be a good idea for nVIDIA ;-). |
|
|
|
|
|
|
#17 |
|
Registered User
|
Here is source code for testcase demonstrating the problem: http://lexa2.ru/lx2/lx2-opengl-vsync...c-test.tar.bz2
To compile this simple demo one would require development headers for glibc, any GLUT 3.x compatible implementation and OpenGL+GLX development headers (including libGLU which had been deprecated as of OpenGL 3.0). Demo code is very quick-n-dirty and isn't portable due to it is using some stuff from GLX and XLib. OTOH it shouldn't be hard to port it to the WGL in case someone would need it. By default at startup demo creates 800x600 sized window with attached GL render context and enters endless loop displaying teapot that is quickly moving up and down. One may use "+" and "-" keys to change the threshold of the internal demo FPS limiter, Alt+Enter or F11 to toggle fullscreen mode, "S" or F2 to toggle vsync and ESC to exit the demo. As a part of GL context initialization demo gets pointer to glXSwapIntervalSGI and call it as glXSwapIntervalSGI(0). This is the bug trigger. Expected behavior: to always get vsync enabled in case I set "Sync to VBlank" in driver CP or export __GL_SYNC_TO_VBLANK environment variable with value set to "1". Actual behavior: vsync is disabled (tearing is easily noticeable, FPS isn't capped to monitor refresh rate) until specifically enabled by demo using "S" or "F2" hotkeys. Upd. Had attached the source tarball to this post just in case. |
|
|
|
|
|
#18 | |
|
Registered User
Join Date: Jan 2007
Posts: 119
|
Thank you very much for reproducing the bug without the need to use wine!
I tried your test and, as expected, switching vsync on/off within the application works, while forcing it does not. |
|
|
|
|
|
|
#19 |
|
NVIDIA Corporation
Join Date: Mar 2005
Posts: 2,487
|
Thanks for the detailed analysis. Bug 839481 is filed to track the fact that __GL_SYNC_TO_VBLANK does not, despite what the README says, override the programmatic swap interval control specified by applications.
lexa2, I don't think the GLX_SGI_swap_control spec states that you can't disable vsync once it's been enabled. The "minimum" it refers to is the minimum number of video frame periods before the next buffer swap, not the minimum value you can ever set the swap interval to. |
|
|
|
|
|
#20 | ||
|
Registered User
|
Quote:
Quote:
|
||
|
|
|
|
|
#21 |
|
NVIDIA Corporation
Join Date: Mar 2005
Posts: 2,487
|
Sorry, you're right; I was thinking of EXT_swap_control, not SGI_swap_control.
|
|
|
|
|
|
#22 |
|
Registered User
|
Yeah and that's the exact specs ambiguity I've been mentioning. SGI_swap_control defaults swap_interval to be 1 and directly forbids setting it to 0. EXT_swap_control permits using 0 as swap_interval and also states that "Calling glXSwapIntervalSGI is equivalent to calling glXSwapIntervalEXT on the current drawable, if one exists". Does this "equivalent" means that when EXT_swap_control is available in OpenGL implementation glXSwapIntervalSGI should be implemented as simple forward to glXSwapIntervalEXT thus allowing 0 as a valid argument isn't clearly stated. Personally I would stick with prohibiting usage of zero as an argument to glXSwapIntervalSGI as allowing it might cause unexpected behavior in older applications that are unaware of EXT_swap_control/glXSwapIntervalEXT existence.
|
|
|
|
|
|
#23 |
|
Registered User
Join Date: Jan 2007
Posts: 119
|
Just tried 290.10 and the issue seems to be still here.
Any news on 839481 ? Thanks |
|
|
|
|
|
#24 |
|
NVIDIA Corporation
Join Date: Mar 2005
Posts: 2,487
|
After discussing it with the OpenGL gurus, it was decided that prohibiting 0 as a value for glXSwapIntervalSGI is not a useful feature, and will not be implemented.
The problem of the nvidia-settings and environment variables not preventing applications from using glXSwapInterval{SGI,EXT} has not yet been fixed. |
|
|
|
![]() |
| Thread Tools | |
|
|