I need some help to investigate a Sacred (DX7 diablo like) crash.
I started from the demo (works perfectly on cedega, crashed on dx9wine).
After some work in the disassembly (IDA/winedbg/softice), I discovered that Sacred is _very_ upset when we do not present to him a 1024x768x16 mode in EnumDisplayModes [they have in their sourcecode a function which returns a pointer on the EnumDisplayModes callback-returned array which points to an appropriate 1024x768x16 mode. If no mode can be found, the return value is NULL, an this NULL-ptr is never checked after the call]. In 1280x1024x16, my dx9wine only presents 1280x1024 modes to Sacred. I haven't fully investigated why, but I've got an immediate workaround: test Sacred with my Xserver in 1024x768x16 !
Next issue, I got something funny: dx9wine is then making my opengl driver (from nvidia closed source drivers) crash ! Basically, after the first [Lock, GetDC, ReleaseDC, Unlock, Flip] call, the next Flip (which is calling glXSwapBuffers) is crashing in the nvidia code :) If I surround the code for glXSwapBuffers by calls to glgetError(), this getError() is crashing ! It seems we messed up the gl driver internals here. Any ideas where to look ?
I've had a bit of a look, and I expect that 1024x786 isn't getting reported by Wine because it's not listed as a mode supported by X either through xrandr or through the standard /etc/X11/XF86Config setup
xrandr -q
will list all supported modes.
The Sacred demo also crashed for me using ATI's drivers, but in glDrawPrimitive and not in glXSwapBuffers, so I exepect the problem with glDrawPrimitive is cascading to glXSwapBuffers with GForces drivers..
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You're right, xrandr is only reporting one mode (which is
1280x1024). This is because TVout is enabled :( With TVout disabled, xrandr reports more modes.
However, as a low priority thing, it would be interresting for wine to add standard modes to the enumerated list (1024x768, 800x600,...) as soon as xrandr provides a higher resolution ones (and have the game run in "windowed" mode - this is what cedega seems to do here, hence no crash on Sacred Demo). More games may then start to work out-of-the-box. What is pretty bad in this case -and possibly with other games - is that Sacred says nothing before crashing, no MessageBox(). Nada.
2/ The gl crash
What is interresting here is that we run correctly the first rendrer loop (lock/getdc/draw/releasedc/unlock/flip). At this point, everyting is OK (glGetError() says 0).
At the end of this loop, the game is doing a lot of things (+relay log is 1million lines before the second render loop), but nothing gl related.
When the second loop starts, the opengl driver in a corrupted state (ie. even a stupid glGetError() crashes !). I do not think it is normal that the gl state/driver can be corrupted whereas we have only executed standard/nongl API calls.
What I am trying to do now to understand this crash:
- trace in the nvidia driver with winedbg to try to understand which surface/pointer/variable got corrupted (and how...).
- Add _a lot_ of glGetError() verbosity between the 2 render loop to understand when (around which standard API call) the gl driver starts to get annoyed. Currently for each relayed API call (!) wine is asked to execute a glGetError() call.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I need some help to investigate a Sacred (DX7 diablo like) crash.
I started from the demo (works perfectly on cedega, crashed on dx9wine).
After some work in the disassembly (IDA/winedbg/softice), I discovered that Sacred is _very_ upset when we do not present to him a 1024x768x16 mode in EnumDisplayModes [they have in their sourcecode a function which returns a pointer on the EnumDisplayModes callback-returned array which points to an appropriate 1024x768x16 mode. If no mode can be found, the return value is NULL, an this NULL-ptr is never checked after the call]. In 1280x1024x16, my dx9wine only presents 1280x1024 modes to Sacred. I haven't fully investigated why, but I've got an immediate workaround: test Sacred with my Xserver in 1024x768x16 !
Next issue, I got something funny: dx9wine is then making my opengl driver (from nvidia closed source drivers) crash ! Basically, after the first [Lock, GetDC, ReleaseDC, Unlock, Flip] call, the next Flip (which is calling glXSwapBuffers) is crashing in the nvidia code :) If I surround the code for glXSwapBuffers by calls to glgetError(), this getError() is crashing ! It seems we messed up the gl driver internals here. Any ideas where to look ?
for the log, see http://norbert.lataille.free.fr/log
I've had a bit of a look, and I expect that 1024x786 isn't getting reported by Wine because it's not listed as a mode supported by X either through xrandr or through the standard /etc/X11/XF86Config setup
xrandr -q
will list all supported modes.
The Sacred demo also crashed for me using ATI's drivers, but in glDrawPrimitive and not in glXSwapBuffers, so I exepect the problem with glDrawPrimitive is cascading to glXSwapBuffers with GForces drivers..
Hi Oliver,
let me give you a status there:
1/ 1024x768x16 crash
You're right, xrandr is only reporting one mode (which is
1280x1024). This is because TVout is enabled :( With TVout disabled, xrandr reports more modes.
However, as a low priority thing, it would be interresting for wine to add standard modes to the enumerated list (1024x768, 800x600,...) as soon as xrandr provides a higher resolution ones (and have the game run in "windowed" mode - this is what cedega seems to do here, hence no crash on Sacred Demo). More games may then start to work out-of-the-box. What is pretty bad in this case -and possibly with other games - is that Sacred says nothing before crashing, no MessageBox(). Nada.
2/ The gl crash
What is interresting here is that we run correctly the first rendrer loop (lock/getdc/draw/releasedc/unlock/flip). At this point, everyting is OK (glGetError() says 0).
At the end of this loop, the game is doing a lot of things (+relay log is 1million lines before the second render loop), but nothing gl related.
When the second loop starts, the opengl driver in a corrupted state (ie. even a stupid glGetError() crashes !). I do not think it is normal that the gl state/driver can be corrupted whereas we have only executed standard/nongl API calls.
What I am trying to do now to understand this crash:
- trace in the nvidia driver with winedbg to try to understand which surface/pointer/variable got corrupted (and how...).
- Add _a lot_ of glGetError() verbosity between the 2 render loop to understand when (around which standard API call) the gl driver starts to get annoyed. Currently for each relayed API call (!) wine is asked to execute a glGetError() call.