Hi, I'm looking at bug #9672 again in the The Sims. The app crashes early on during initialisation in DirectDraw. The problem occurs after CreateSurface returns an error, since it would appear that the DDSURFACEDESC passed into the call is foobar. This would lead me to conclude that something on the lead up to that call is precipitating that rogue call.
I have a legal Windows XP and I wish to trace the calls leading up to this point with real Windows/DirectX to compare with what is happening to Wine so that I can assess what is upsetting the application, since I can't see anything in the Wine trace prior to that that looks suspicious.
Does anyone have any experience with tracing apps in real Windows in the context of Wine development?
Should I use a profiler or is there a simpler method?
Cheers, Ralph
Ralph Little littlesincanada@yahoo.co.uk wrote:
Does anyone have any experience with tracing apps in real Windows in the context of Wine development?
Should I use a profiler or is there a simpler method?
Try logger.exe from Debugging Tools For Windows.
Am Dienstag, 31. Januar 2012, 17:29:23 schrieb Ralph Little:
Hi, I'm looking at bug #9672 again in the The Sims. The app crashes early on during initialisation in DirectDraw. The problem occurs after CreateSurface returns an error, since it would appear that the DDSURFACEDESC passed into the call is foobar. This would lead me to conclude that something on the lead up to that call is precipitating that rogue call. From looking at the bug report(ddsurfacedesc.ddpfPixelFormat.dwFlags = 0) I
think it's worth writing a test to see how Windows responds to the CreateSurface call before spending too much time debugging this. It is quite possible that Windows creates the surface just fine.
Hi Stefan, I did put together a test for this and DirectX does indeed return DDERR_INVALIDPARMS.
Here is a snippet that encapsulates what I tried:
======================== IDirectDraw * pDD = NULL; IDirectDrawSurface * pDDSPrimary = NULL; DDSURFACEDESC ddsd;
...<initialisation etc>...
memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_ZBUFFER; ddsd.dwHeight = 600; ddsd.dwWidth = 800; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
hr = pDD->CreateSurface(&ddsd, &pDDSPrimary, NULL); ========================
DirectX returns DDERR_INVALIDPARAMS from CreateSurface. I have tried to recreate as much a possible the graphical situation as it would be in The Sims at this point. Fullscreen, with 800x600 video mode.
I assume that if the caller specifies DDSCAPS_ZBUFFER, the you must also specify some PIXEL format information. DDSD_PIXELFORMAT is present, but there are no format flags.
I have to admit that I am a bit of a novice when it comes to DirectX so any guidance here would be helpful. I see that the lpSurface is NULL, which I thought was an error. However, I see that this is optional if the caller wishes the system to manage the surface memory.
Any error returned by this function the Sims at this point to causes it to crash. Therefore, it seems to me that if it succeeds in Windows, it must have passed something different. If only we could see the source :D Cheers, Ralph
From: Stefan Dösinger stefandoesinger@gmx.at To: wine-devel@winehq.org; Ralph Little littlesincanada@yahoo.co.uk Sent: Tuesday, January 31, 2012 12:08:51 PM Subject: Re: Profiing windows apps
Am Dienstag, 31. Januar 2012, 17:29:23 schrieb Ralph Little:
Hi, I'm looking at bug #9672 again in the The Sims. The app crashes early on during initialisation in DirectDraw. The problem occurs after CreateSurface returns an error, since it would appear that the DDSURFACEDESC passed into the call is foobar. This would lead me to conclude that something on the lead up to that call is precipitating that rogue call.
From looking at the bug report(ddsurfacedesc.ddpfPixelFormat.dwFlags = 0) I think it's worth writing a test to see how Windows responds to the CreateSurface call before spending too much time debugging this. It is quite possible that Windows creates the surface just fine.
Hi,
Am Dienstag, 31. Januar 2012, 21:51:01 schrieb Ralph Little:
IDirectDraw * pDD = NULL; IDirectDrawSurface * pDDSPrimary = NULL; DDSURFACEDESC ddsd;
Take a look at dlls/ddraw/tests/ddraw*.c
...<initialisation etc>...
Make sure you use the version of the interface the game uses. There are some behavioral differences between them. E.g. with zbuffers DDSURFACEDESC(IDirectDraw, IDirectDraw2) has dwZBufferBitDepth(and DDSD_ZBUFFERBITDEPTH), while DDSURFACEDESC2(IDirectDraw4, IDirectDraw7) always uses a pixel format.
As far as I can see from the bug report the game is using IDirectDraw4.
memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_ZBUFFER;
Is it really trying to create a system memory z buffer? (Ok, I just saw this in the logs attached to the bug report - that's really odd).
ddsd.dwHeight = 600; ddsd.dwWidth = 800; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
Try to set ddsd.ddpfPixelFormat.dwZBufferBitDepth to e.g. 16 and ddsd.ddpfPixelFormat.dwZBitMask to 0x0000ffff. Keep dwFlags set to 0. Als try to keep dwSize at 0.
I assume that if the caller specifies DDSCAPS_ZBUFFER, the you must also specify some PIXEL format information. DDSD_PIXELFORMAT is present, but there are no format flags.
Basically that, or dwZBufferBitDepth. See zbufferbitdepth_test in dlls/ddraw/tests/dsurface.c for some tests on this. (Don't add any new tests there btw - use tests/ddraw*.c).
I have to admit that I am a bit of a novice when it comes to DirectX so any guidance here would be helpful. I see that the lpSurface is NULL, which I thought was an error. However, I see that this is optional if the caller wishes the system to manage the surface memory.
Correct.
Any error returned by this function the Sims at this point to causes it to crash. Therefore, it seems to me that if it succeeds in Windows, it must have passed something different. If only we could see the source :D
If the testing doesn't reveal anything, look out for IDirectDraw::GetCaps calls in the logs or IDirect3Dx::EnumZBufferFormats. IDirectDraw::GetCaps returns a DDCAPS structure which has dwZBufferBitDepths containing some flags for z buffer bit depths. EnumZBufferFormats calls a callback multiple times with available DDPIXELFORMAT structures. The application may not like some flags we set there.
Also please attach a full +ddraw log to the bug report. If it is too big compress it. bzip2 should do a pretty decent job, if all fails try lrzip.
Hi Stefan,
If the testing doesn't reveal anything, look out for IDirectDraw::GetCaps calls in the logs or IDirect3Dx::EnumZBufferFormats. IDirectDraw::GetCaps returns a DDCAPS structure which has dwZBufferBitDepths containing some flags for z buffer bit depths. EnumZBufferFormats calls a callback multiple times with available DDPIXELFORMAT structures. The application may not like some flags we set there.
You know, my gut says that this is the right place to look, particularly IDirect3Dx::EnumZBufferFormats.
I see why you suggest this: what if none are returned to the application? I will look into it. What The Sims is passing to CreateSurface just looks wrong.
In the meantime, I will generate a full ddraw trace and add it to the bug log as you suggest and then check it through.
Cheers, and thanks for the help. It is much appreciated.
Ralph
From: Stefan Dösinger stefandoesinger@gmx.at To: wine-devel@winehq.org; Ralph Little littlesincanada@yahoo.co.uk Sent: Wednesday, February 1, 2012 11:52:15 AM Subject: Re: Profiing windows apps
Hi,
Am Dienstag, 31. Januar 2012, 21:51:01 schrieb Ralph Little:
IDirectDraw * pDD = NULL; IDirectDrawSurface * pDDSPrimary = NULL; DDSURFACEDESC ddsd;
Take a look at dlls/ddraw/tests/ddraw*.c
...<initialisation etc>...
Make sure you use the version of the interface the game uses. There are some behavioral differences between them. E.g. with zbuffers DDSURFACEDESC(IDirectDraw, IDirectDraw2) has dwZBufferBitDepth(and DDSD_ZBUFFERBITDEPTH), while DDSURFACEDESC2(IDirectDraw4, IDirectDraw7) always uses a pixel format.
As far as I can see from the bug report the game is using IDirectDraw4.
memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_ZBUFFER;
Is it really trying to create a system memory z buffer? (Ok, I just saw this in the logs attached to the bug report - that's really odd).
ddsd.dwHeight = 600; ddsd.dwWidth = 800; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
Try to set ddsd.ddpfPixelFormat.dwZBufferBitDepth to e.g. 16 and ddsd.ddpfPixelFormat.dwZBitMask to 0x0000ffff. Keep dwFlags set to 0. Als try to keep dwSize at 0.
I assume that if the caller specifies DDSCAPS_ZBUFFER, the you must also specify some PIXEL format information. DDSD_PIXELFORMAT is present, but there are no format flags.
Basically that, or dwZBufferBitDepth. See zbufferbitdepth_test in dlls/ddraw/tests/dsurface.c for some tests on this. (Don't add any new tests there btw - use tests/ddraw*.c).
I have to admit that I am a bit of a novice when it comes to DirectX so any guidance here would be helpful. I see that the lpSurface is NULL, which I thought was an error. However, I see that this is optional if the caller wishes the system to manage the surface memory.
Correct.
Any error returned by this function the Sims at this point to causes it to crash. Therefore, it seems to me that if it succeeds in Windows, it must have passed something different. If only we could see the source :D
If the testing doesn't reveal anything, look out for IDirectDraw::GetCaps calls in the logs or IDirect3Dx::EnumZBufferFormats. IDirectDraw::GetCaps returns a DDCAPS structure which has dwZBufferBitDepths containing some flags for z buffer bit depths. EnumZBufferFormats calls a callback multiple times with available DDPIXELFORMAT structures. The application may not like some flags we set there.
Also please attach a full +ddraw log to the bug report. If it is too big compress it. bzip2 should do a pretty decent job, if all fails try lrzip.