Hi,
the whole yesterday I was hunting a problem when staring a program with wine. Now I'm at a point I don't know what to do next. May be somebody can give me an hint?
Here are the last lines of the trace+ddraw output:
trace:ddraw:Main_DirectDrawSurface_Lock (0x40405b50)->Lock((nil),0x408bf960,00000001,00000000) trace:ddraw:Main_DirectDrawSurface_Lock - locking flags : DDLOCK_WAIT trace:ddraw:d3ddevice_lock_update copying back buffer to main memory with rectangle (0x0) - (800x600). trace:ddraw:Main_DirectDrawSurface_Lock locked surface returning description : - DDSD_CAPS : DDSCAPS_BACKBUFFER DDSCAPS_COMPLEX DDSCAPS_FLIP DDSCAPS_3DDEVICE DDSCAPS_VIDEOMEMORY DDSCAPS_LOCALVIDMEM - DDSD_HEIGHT : 600 - DDSD_WIDTH : 800 - DDSD_PITCH : 1600 - DDSD_LPSURFACE : 0x5f0d0000 - DDSD_PIXELFORMAT : ( DDPF_RGB , RGB bits: 16, R f800 G 07e0 B 001f) trace:ddraw:Main_DirectDrawSurface_Unlock (0x40405b50)->Unlock((nil)) trace:ddraw:DIB_DirectDrawSurface_Blt (0x403f5768)->(0x61885c,0x40405b50,0x61886c,01000000,(nil)) trace:ddraw:DIB_DirectDrawSurface_Blt destrect :0x0-800x600 trace:ddraw:DIB_DirectDrawSurface_Blt srcrect :0x0-800x600 trace:ddraw:DIB_DirectDrawSurface_Blt flags: DDBLT_WAIT trace:ddraw:d3ddevice_blt using direct buffer to buffer copy. trace:ddraw:upload_surface_to_tex_memory_init initialized texture upload for level 0 with conversion 0. trace:ddraw:Main_DirectDraw_CreateSurface (0x403f5418)->(0x61741ba0,0x60d0aedc,(nil)) trace:ddraw:Main_DirectDraw_CreateSurface Requesting surface desc : - DDSD_CAPS : DDSCAPS_TEXTURE DDSCAPS2_TEXTUREMANAGE - DDSD_HEIGHT : 128 - DDSD_WIDTH : 256 - DDSD_PIXELFORMAT : ( DDPF_ALPHAPIXELS DDPF_RGB , RGB bits: 16, R 7c00 G 03e0 B 001f A 8000) trace:ddraw:HAL_DirectDrawSurface_Construct (0x60f501b8,0x403f5418,0x61741ac0) trace:ddraw:DIB_DirectDrawSurface_Construct (0x60f501b8)->(0x403f5418,0x60f503b4) trace:ddraw:Main_DirectDrawSurface_Construct (0x60f501b8)->(0x403f5418,0x60f503b4) trace:ddraw:DIB_DirectDrawSurface_Construct (256x128, pitch=512) trace:ddraw:create_dib DIBSection at : 0x62100000 trace:ddraw:d3dtexture_create GL texture created for surface 0x60f501b8 (private data at 0x60f50058)
The appropriate source code:
ENTER_GL(); if (surf->mipmap_level == 0) { glGenTextures(1, &(private->tex_name)); if (private->tex_name == 0) ERR("Error at creation of OpenGL texture ID !\n"); TRACE(" GL texture id is : %d.\n", private->tex_name); private->__global_dirty_flag = (at_creation == FALSE ? SURFACE_MEMORY_DIRTY : SURFACE_MEMORY); private->global_dirty_flag = &(private->__global_dirty_flag); } else { private->tex_name = ((IDirect3DTextureGLImpl *) (main->tex_private))->tex_name; TRACE(" GL texture id reusing id %d from surface %p (private at %p)).\n", private->tex_name, main, main->tex_private); private->global_dirty_flag = &(((IDirect3DTextureGLImpl *) (main->tex_private))->__global_dirty_flag); } LEAVE_GL();
A printf showed me, that the call of glGenTextures didn't come back. That's strage because d3dtexture_create and glGenTextures are called a lot of times before without problems? If I delete glGenTextures it works but...
Bye, Michael
Hi,
Am Mo, den 15.03.2004 schrieb Michael Schlüter um 12:38:
A printf showed me, that the call of glGenTextures didn't come back. That's strage because d3dtexture_create and glGenTextures are called a lot of times before without problems? If I delete glGenTextures it works but...
I'm now sure that the call to glGenTextures didn't return. I can think of three reasons:
1. Another wine thread is just doing a call to libGL 2. The libGL of Nvidia has a bug 3. both of the above
Maybe somebody ca take my by the hand to find out what the cause is?
Bye, Michael
I'm now sure that the call to glGenTextures didn't return. I can think of three reasons:
- Another wine thread is just doing a call to libGL
- The libGL of Nvidia has a bug
- both of the above
Maybe somebody ca take my by the hand to find out what the cause is?
If you run with +ddraw,+tid and you get two different numbers before the lines, you are hit by a bug that will be a bitch to fix : multithreaded Direct3D applications...
This is something I have no real clue yet how to fix in the 'general' case (I have some ideas for two of the games I have that exhibit the issue).
Lionel
I'm now sure that the call to glGenTextures didn't return. I can think of three reasons:
- Another wine thread is just doing a call to libGL
- The libGL of Nvidia has a bug
- both of the above
If you run with +ddraw,+tid and you get two different numbers before the lines, you are hit by a bug that will be a bitch to fix : multithreaded Direct3D applications...
yes, that's the case. glGenTextures seems to be the first gl call of the new thread.
This is something I have no real clue yet how to fix in the 'general' case (I have some ideas for two of the games I have that exhibit the issue).
I did a "bad hack" and replaced glGenTextures with own code (only a static variable that gets increased after each call). That works fine for me.
After google-ing a bit I think it is necessary to make a glXmakeCurrent() call before using a gl-call in a new thread (at least for the Nvidia GL-driver, DRI should work). Not all GL-calls are affected but definitely the textures calls.
Bye, Michael
After google-ing a bit I think it is necessary to make a glXmakeCurrent() call before using a gl-call in a new thread (at least for the Nvidia GL-driver, DRI should work). Not all GL-calls are affected but definitely the textures calls.
Well, as said before, Wine is completely broken regarding multi-threaded Direct3D applications.
It worked before because our pthread emulation was broken which lead the GL libraries to not find out at all that they were running in a multi-threaded environment (so the contxt was 'shared' between threads).
I would be pleased to get some ideas as to the way to handle this in a way that does not kill completely our performance :-)
Lionel
On Fri, 19 Mar 2004 19:09:39 +0100, Lionel Ulmer wrote:
It worked before because our pthread emulation was broken which lead the GL libraries to not find out at all that they were running in a multi-threaded environment (so the contxt was 'shared' between threads).
Well, if shared context worked OK then I guess we could figure out a way to trick the GL libraries once again.
The other approaches (marshalling etc) seem really not good to me.
Well, if shared context worked OK then I guess we could figure out a way to trick the GL libraries once again.
Well, an easy way to trick them is to re-break again the PTHREAD emulation patch by reverting this :
http://cvs.winehq.com/patch.py?id=10090
But the problem is then what to do if another library FOO is used multi-threaded in Wine and require pthread emulation ? You can't really say 'OK, we emulate pthread for library FOO but not for OpenGL'.
And games like FIFA2002 never worked for me on the NVIDIA drivers because of threading issues even when some others did...
The other approaches (marshalling etc) seem really not good to me.
Yeah, but I fear it's the only way to go if we want to support all types of GL libraries out there (DRI, ATI and NVIDIA).
Lionel
On Sat, 2004-03-20 at 10:12, Lionel Ulmer wrote:
The other approaches (marshalling etc) seem really not good to me.
Yeah, but I fear it's the only way to go if we want to support all types of GL libraries out there (DRI, ATI and NVIDIA).
Or playing games with stack switches and hoping the scheduler doesn't intervene ... :)
On Sat, 2004-03-20 at 10:12, Lionel Ulmer wrote:
But the problem is then what to do if another library FOO is used multi-threaded in Wine and require pthread emulation ? You can't really say 'OK, we emulate pthread for library FOO but not for OpenGL'.
Well thinking about it actually we could with sufficient magic. For instance we could load and link libGL ourselves or possibly use filter libraries.... anything is possible with enough pain and assembly! :)