Wined3d isn't thread safe yet. Threading will cause lots of problems because when you call MakeActive with the OpenGL context it only makes the context active on the current thread so when you switch threads you may be using a different OpenGL context. This also means that wined3d cannot support multiple concurrent devices, unless the application is using one device per thread, because the OpenGL context isn't being switched when the device changes.
I've written a little function: void check_thread(IWineD3DDeviceImpl *This) { DWORD tid = GetCurrentThreadId(); if(This->LastTid != tid) { WARN(" (%p) Current thread has changed! Updating OpenGL context\n", This); TRACE(" (%p) Old tid=0x%lx, new tid=0x%lx\n", This, This->LastTid, tid);
/* Find the implicit swapchain and restore the GL context */ if(This->swapchains) { if(This->swapchains->swapchain) { IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) This->swapchains->swapchain; /* Restore the glX context */ if(glXMakeCurrent(swapchain->display, swapchain->win, swapchain->glCtx) == FALSE) { ERR("Error in setting current context (display %p context %p drawable %ld)!\n", swapchain->display, swapchain->glCtx, swapchain->win); } checkGLcall("glXMakeCurrent");
/* Todo: Restore the viewport */ } else { ERR(" (%p) Swapchain list found, but it doesn't contain a swapchain\n", This); } } else { ERR(" (%p) No swapchains found - Expect a crash\n", This); }
This->LastTid = tid; } }
It restored the glx context based on the one in the implicit swapchain. I call it in WineD3DDeviceImpl_Clear. This solved the GL crash, and I rush into a blocked Desktop in surface UnlockRect, which can only be solved by killing wine via acpi hotkeys or ssh. Eighter my solution is incorrect or these crashes are not related.
Stefan
PS: I've a Direct3D 9 test if you are interested.