PDA

View Full Version : nVidia + wglMakeCurrent() + multiple threads



skynet
05-19-2010, 09:36 AM
I have an application which is using 2 threads and 3 contexts.
Thread T1 renders using render context RC1, while thread T2 renders most stuff using RC2 and some stuff using RC3.

So, T2 is calling wglMakeCurrent() once a frame, while T1 might render something else asynchronously.

Unfortunately, wglMakeCurrent() sometimes failes with "the handle is invalid" and other obsure errors. The handles in question are NOT invalid!
The error does not occur, if "Threaded optimization" is turned off in the NVidia control panel.

This happens on WinXP64 SP2, GF470GTX, 197.44 drivers.
The problem also occured on other hardware and older drivers.

Do you have any advice? Thanks in advance.

Update:
The error is not dependent on our application rendering in multiple threads. A single rendering thread also triggers the problem. Having two rendering threads only seems to make it worse.

To sum up the problem: When "Threaded optimization" is turned on, wglMakeCurrent() often failes for no apparent reason.

mfort
05-19-2010, 12:06 PM
I remember I had similar problem some time ago .
I fixed the problem by calling wglMakeCurrent() in a loop.
It never made more then 2 iterations.

Piers Daniell
05-20-2010, 01:43 PM
Are you able to construct a simple repro app for this problem?

skynet
05-20-2010, 02:42 PM
Hi Piers,

Unfortunately, I wasn't able to reproduce it in a simple program, yet. Could it be somehow connected to the window framework in use? We are using wxWidgets.

Maybe we could approach from both sides... under what circumstances is wglMakeCurrent() allowed to fail?

For instance, I observed (unrelated to my original problem!) that calling wglMakeCurrent(0,0) more than once returns FALSE. This is reproducible and occures on any driver or hardware (be it nVidia or ATI). I have found no documentation that told me "thou shalt not call wglMakeCurrent(0,0) twice".
Maybe there are other undocumented rules for wglMakeCurrent() ?!

Piers Daniell
05-20-2010, 03:39 PM
> Unfortunately, I wasn't able to reproduce it in a simple program, yet.
Is the full repro app you are using available so that I can use to repro?

> under what circumstances is wglMakeCurrent() allowed to fail?
Probably quite a lot. Actually some of the functionality of this call is implemented in opengl32.dll and gdi32.dll, so it'll be hard to provide an exhaustive list.

> Unfortunately, wglMakeCurrent() sometimes failes with "the handle is invalid" and other obsure errors.
Do you use GetLastError() to get the error codes? Can you tell me what error codes you've seen so far.

mfort
05-21-2010, 02:58 AM
We are not using wxWidgets and have the same problem. We call it in a loop with Sleep(10). It never fails then. So there must be some race condition inside the driver that is only temporary. The problem exists for several years.

skynet
05-21-2010, 03:55 AM
The error codes I get are:

6 : "The operation is invalid" (most often)
2004: "The requested transformation is not supported" (less often)
0: "The operation completed successfully" (rare)

skynet
05-21-2010, 08:39 AM
We call it in a loop with Sleep(10). It never fails then.
Indeed, this is a workaround!

I did some research today to see if I can come up with a small example that exhibits the problem. I could reproduce it by switching contexts several times inside one frame (i.e. no SwapBuffers() inbetween). Unfortunately, it cannot reliably reproduce the problem on all machines tested, while the original app still fails very reliable :-)

sqrt[-1]
05-23-2010, 11:33 PM
I am not sure if it is related, but the Nvidia multi-thread drivers seem to call an internal wglGetPixelFormat call on the first glGetError() after SwapBuffers. This internal call occurs on a different thread that does not typically have an OpenGL conext.

I have noticed this is every app while debugging with GLIntercept.

Piers Daniell
06-02-2010, 05:07 PM
It appears this issue is caused by a bug in the driver. We are working on a fix.

In the meantime, another possible work around for this issue is to ensure that any calls to SwapBuffers() are called while an OpenGL context is active.

Piers Daniell
08-10-2010, 01:22 PM
This issue should be fixed now with the latest public release drivers from nvidia.com.