https://bugs.winehq.org/show_bug.cgi?id=39346
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Summary|Lego Rock Raiders crashes |Lego Rock Raiders crashes |on startup |on startup | |(d3drm_device_init doesn't | |handle device version 3 | |case) Keywords| |download URL| |https://archive.org/downloa | |d/LEGORockRaidersWindows/LE | |GO_Rock_Raiders_Win_Files_E | |N.7z Component|-unknown |directx-d3d CC| |focht@gmx.net
--- Comment #10 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming. Found a download for debugging:
https://archive.org/download/LEGORockRaidersWindows/LEGO_Rock_Raiders_Win_Fi...
--- snip --- $ WINEDEBUG=+seh,+relay,+d3drm,+loaddll WINEDLLOVERRIDES=d3drm=b wine LegoRR.exe >>log.txt 2>&1 ... 0100:Call d3drm.Direct3DRMCreate(0031f0dc) ret=004784e7 ... 0100:Ret d3drm.Direct3DRMCreate() retval=00000000 ret=004784e7 ... 0100:trace:d3drm:d3drm1_QueryInterface iface 0018C408, riid {4516ec83-8f20-11d0-9b6d-0000c0781bc3}, out 00506914. 0100:trace:d3drm:d3drm3_AddRef 0018C410 increasing refcount to 1. 0100:trace:d3drm:d3drm3_CreateDeviceFromSurface iface 0018C410, guid {84e63de0-46aa-11cf-816f-0000c020156e}, ddraw 00188FAC, backbuffer 0018C488, flags 0, device 00506918. 0100:trace:d3drm:d3drm_device_create device 0031F090, d3drm 0018C408. ... 0100:trace:d3drm:d3drm_device3_GetDirect3DDevice2 iface 00187960, d3d_device 0031F0E8. 0100:fixme:d3drm:d3drm_device3_SetBufferCount iface 00187960, count 2 stub! ... 0100:fixme:d3drm:d3drm_device3_FindPreferredTextureFormat iface 00187960, bitdepths 2048, flags 0x4, pf 0031EEFC stub! 0100:fixme:d3drm:d3drm_device3_FindPreferredTextureFormat iface 00187960, bitdepths 1024, flags 0, pf 0031EEFC stub! ... 0100:fixme:d3drm:d3drm_device3_Update iface 00187960 stub! ... 0100:trace:d3drm:d3drm3_CreateViewport iface 0018C410, device 00187960, camera 0288FDB0, x 16, y 13, width 151, height 151, viewport 017C6C60. 0100:trace:d3drm:d3drm_viewport_create viewport 0031EEC4, d3drm 0018C408. 0100:trace:d3drm:d3drm_viewport2_Init iface 0288D5C4, device 00187960, camera 0288FDB0, x 16, y 13, width 151, height 151. 0100:trace:d3drm:d3drm1_AddRef 0018C408 increasing refcount to 37. 0100:trace:d3drm:d3drm_device3_GetDirect3DDevice iface 00187960, d3d_device 0031EE54! 0100:trace:d3drm:d3drm_frame3_QueryInterface iface 0288FDB0, riid {eb16cb03-d271-11ce-ac48-0000c03825a1}, out 0288D5BC. 0100:trace:d3drm:d3drm_frame1_AddRef iface 0288FDA8. 0100:trace:d3drm:d3drm_frame3_AddRef 0288FDB0 increasing refcount to 3. 0100:trace:d3drm:d3drm_viewport2_SetAppData iface 0288D5C4, data 0x17c6c50 0100:fixme:d3drm:d3drm_device3_Update iface 00187960 stub! ... 0100:Call wined3d.wined3d_mutex_lock() ret=00ca4998 0100:Ret wined3d.wined3d_mutex_lock() retval=00000000 ret=00ca4998 0100:Call wined3d.wined3d_texture_set_color_key(0415ed48,00000008,0031ee74) ret=00ca4ac9 0100:Ret wined3d.wined3d_texture_set_color_key() retval=00000000 ret=00ca4ac9 0100:Call wined3d.wined3d_mutex_unlock() ret=00ca4ad3 0100:Ret wined3d.wined3d_mutex_unlock() retval=00000000 ret=00ca4ad3 0100:trace:seh:dispatch_exception code=c0000005 flags=0 addr=004809BC ip=004809bc tid=0100 0100:trace:seh:dispatch_exception info[0]=00000000 0100:trace:seh:dispatch_exception info[1]=00000000 0100:trace:seh:dispatch_exception eax=00000000 ebx=00000000 ecx=00000000 edx=0031eebc esi=01665508 edi=005415d4 0100:trace:seh:dispatch_exception ebp=0031f1e4 esp=0031eebc cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00210212 0100:trace:seh:call_vectored_handlers calling handler at 7B00F270 code=c0000005 flags=0 0100:trace:seh:call_vectored_handlers handler at 7B00F270 returned 0 0100:trace:seh:call_stack_handlers calling handler at 00496A98 code=c0000005 flags=0 0100:Call KERNEL32.UnhandledExceptionFilter(0031e95c) ret=00495ffa ... wine: Unhandled page fault on read access to 00000000 at address 004809BC (thread 0100), starting debugger... --- snip ---
Disassembly of crash site:
--- snip --- 00480910 | sub esp,54 | 00480913 | mov eax,dword ptr ds:[50691C] | 00480918 | lea edx,dword ptr ss:[esp] | 0048091C | mov dword ptr ss:[esp+4],50 | 00480924 | mov dword ptr ss:[esp+8],3F800000 | 0048092C | mov dword ptr ss:[esp+C],3F800000 | 00480934 | mov dword ptr ss:[esp+10],3F800000 | 0048093C | mov dword ptr ss:[esp+14],3F800000 | 00480944 | mov dword ptr ss:[esp+18],0 | 0048094C | mov dword ptr ss:[esp+1C],0 | 00480954 | mov dword ptr ss:[esp+20],0 | 0048095C | mov dword ptr ss:[esp+24],0 | 00480964 | mov dword ptr ss:[esp+28],0 | 0048096C | mov dword ptr ss:[esp+2C],0 | 00480974 | mov dword ptr ss:[esp+30],0 | 0048097C | mov dword ptr ss:[esp+34],0 | 00480984 | mov dword ptr ss:[esp+38],0 | 0048098C | mov dword ptr ss:[esp+3C],0 | 00480994 | mov dword ptr ss:[esp+40],0 | 0048099C | mov dword ptr ss:[esp+44],0 | 004809A4 | mov dword ptr ss:[esp+48],0 | 004809AC | mov dword ptr ss:[esp+4C],0 | 004809B4 | mov dword ptr ss:[esp+50],0 | 004809BC | mov ecx,dword ptr ds:[eax] | *boom* 004809BE | push edx | 004809BF | push eax | 004809C0 | call dword ptr ds:[ecx+2C] | --- snip ---
Using 'find references to address':
--- snip --- 00478557 push legorr.50691C 00478B90 mov eax,dword ptr ds:[50691C] 00478BB2 mov eax,dword ptr ds:[50691C] 00478C0E mov eax,dword ptr ds:[50691C] 00480913 mov eax,dword ptr ds:[50691C] 004809F1 mov edx,dword ptr ds:[50691C] ... --- snip ---
We arrive here:
--- snip --- 004784E2 | call JMP.&_Direct3DRMCreate@4 | 004784E7 | test eax,eax | 004784E9 | jne legorr.4785A6 | 004784EF | mov eax,dword ptr ss:[esp+4] | 004784F3 | push legorr.506914 | 004784F8 | push legorr.4A0BD8 | 004784FD | push eax | 004784FE | mov ecx,dword ptr ds:[eax] | 00478500 | call dword ptr ds:[ecx] | d3drm.d3drm1_QueryInterface 00478502 | test eax,eax | 00478504 | jne legorr.4785A6 | 0047850A | mov eax,dword ptr ss:[esp+18] | 0047850E | lea ecx,dword ptr ss:[esp+8] | 00478512 | push ecx | 00478513 | push legorr.4A0338 | 00478518 | mov edx,dword ptr ds:[eax] | 0047851A | push eax | 0047851B | call dword ptr ds:[edx] | ddraw_surface4_QueryInterface 0047851D | mov ecx,dword ptr ss:[esp+8] | 00478521 | mov eax,dword ptr ds:[506914] | 00478526 | push legorr.506918 | 0047852B | push 0 | 0047852D | mov edx,dword ptr ds:[eax] | 0047852F | push ecx | 00478530 | mov ecx,dword ptr ss:[esp+20] | 00478534 | push ecx | 00478535 | push esi | 00478536 | push eax | 00478537 | call dword ptr ds:[edx+3C] | d3drm3_CreateDeviceFromSurface 0047853A | mov esi,eax | 0047853C | test esi,esi | 0047853E | jne legorr.47858F | 00478540 | mov eax,dword ptr ds:[506918] | 00478545 | lea ecx,dword ptr ss:[esp+10] | 00478549 | push ecx | 0047854A | push eax | 0047854B | mov edx,dword ptr ds:[eax] | 0047854D | call dword ptr ds:[edx+98] | d3drm_device3_GetDirect3DDevice2 00478553 | mov eax,dword ptr ss:[esp+10] | 00478557 | push legorr.50691C | 0047855C | push legorr.4A06D8 | 00478561 | push eax | 00478562 | mov edx,dword ptr ds:[eax] | 00478564 | call dword ptr ds:[edx] | d3d_device2_QueryInterface --- snip ---
Last call returns 0x80004002
Armed with that info, adding 'ddraw' to debug channels:
--- snip --- ... 0100:trace:d3drm:Direct3DRMCreate d3drm 0031F114. 0100:trace:d3drm:d3drm1_QueryInterface iface 001767A0, riid {4516ec83-8f20-11d0-9b6d-0000c0781bc3}, out 00506914. 0100:trace:d3drm:d3drm3_AddRef 001767A8 increasing refcount to 1. 0100:trace:ddraw:ddraw_surface4_QueryInterface iface 001765AC, riid {6c14db81-a733-11ce-a521-0020af0be560}, object 0031F118. 0100:trace:ddraw:ddraw_surface7_QueryInterface iface 001765A8, riid {6c14db81-a733-11ce-a521-0020af0be560}, object 0031F118. 0100:trace:ddraw:ddraw_surface1_AddRef iface 001765B8 increasing refcount to 1. 0100:trace:ddraw:ddraw_surface_add_iface 001765A8 increasing iface count to 2. 0100:trace:ddraw:ddraw_surface7_QueryInterface (001765A8) returning IDirectDrawSurface interface at 001765B8 0100:trace:d3drm:d3drm3_CreateDeviceFromSurface iface 001767A8, guid {84e63de0-46aa-11cf-816f-0000c020156e}, ddraw 0016EE24, backbuffer 001765B8, flags 0, device 00506918. 0100:trace:d3drm:d3drm_device_create device 0031F0C8, d3drm 001767A0. ... 0100:trace:ddraw:ddraw1_CreateSurface iface 0016EE24, surface_desc 0031F020, surface 0031F09C, outer_unknown 00000000. 0100:trace:ddraw:ddraw_surface_create ddraw 0016EE18, surface_desc 0031EF14, surface 0031EF10, outer_unknown 00000000, version 1. 0100:trace:ddraw:ddraw_surface_create Requesting surface desc: 0100:trace:ddraw:DDRAW_dump_members - DDSD_CAPS : DDSCAPS_ZBUFFER 0100:trace:ddraw:DDRAW_dump_members - DDSD_HEIGHT : 480 0100:trace:ddraw:DDRAW_dump_members - DDSD_WIDTH : 640 0100:trace:ddraw:DDRAW_dump_members - DDSD_PIXELFORMAT : ( DDPF_ZBUFFER , Z bits: 16) 0100:trace:ddraw:ddrawformat_from_wined3dformat Returning: ( DDPF_RGB , RGB bits: 16, R 0x0000f800 G 0x000007e0 B 0x0000001f) ... 0100:trace:ddraw:ddraw1_QueryInterface iface 0016EE24, riid {6aae1ec1-662a-11d0-889d-00aa00bbb76a}, object 0031F098. 0100:trace:ddraw:ddraw7_QueryInterface iface 0016EE18, riid {6aae1ec1-662a-11d0-889d-00aa00bbb76a}, out 0031F098. 0100:trace:ddraw:ddraw7_QueryInterface Returning Direct3D2 interface 0016EE30. ... 0100:trace:ddraw:d3d2_CreateDevice iface 0016EE30, riid {a4665c60-2673-11cf-a31a-00aa00b93356}, surface 001765B8, device 0031F094. 0100:trace:ddraw:d3d_device_create ddraw 0016EE18, target 001765A8, version 2, device 0031EF8C, outer_unknown 00000000. 0100:trace:ddraw:ddraw_surface1_AddRef iface 001765B8 increasing refcount to 3. 0100:trace:ddraw:ddraw_surface1_QueryInterface iface 001765B8, riid {06675a80-3b9b-11d2-b92f-00609797ea5b}, object 0031EEF4. 0100:trace:ddraw:ddraw_surface7_QueryInterface iface 001765A8, riid {06675a80-3b9b-11d2-b92f-00609797ea5b}, object 0031EEF4. 0100:trace:ddraw:ddraw_surface7_AddRef iface 001765A8 increasing refcount to 1. 0100:trace:ddraw:ddraw_surface_add_iface 001765A8 increasing iface count to 3. 0100:trace:ddraw:ddraw_surface7_QueryInterface (001765A8) returning IDirectDrawSurface7 interface at 001765A8 0100:trace:ddraw:ddraw_surface7_GetAttachedSurface iface 001765A8, caps 00CCE338, attachment 0031EEF8. 0100:trace:ddraw:ddraw_surface7_GetAttachedSurface head_surface 001765A8, looking for caps 0x20000, 0, 0, 0. 0100:trace:ddraw:ddraw_surface7_GetAttachedSurface Surface 00172070, caps 0x1000e238, 0, 0, 0. 0100:trace:ddraw:ddraw_surface7_GetAttachedSurface Surface 0017AF20, caps 0x10024000, 0, 0, 0. 0100:trace:ddraw:ddraw_surface7_GetAttachedSurface head_surface 001765A8, returning surface 0017AF20. ... 0100:trace:ddraw:d3d_device_create Created device 0019F2C8. 0100:trace:ddraw:d3d2_Release iface 0016EE30. 0100:trace:ddraw:ddraw1_Release 0016EE18 decreasing refcount to 2. 0100:trace:ddraw:d3d_device2_QueryInterface iface 0019F2D0, riid {64108800-957d-11d0-89ab-00a0c9054129}, out 0031F090. 0100:trace:ddraw:d3d_device_inner_QueryInterface iface 0019F2D8, riid {64108800-957d-11d0-89ab-00a0c9054129}, out 0031F090. 0100:trace:ddraw:d3d_device1_AddRef iface 0019F2D4. 0100:trace:ddraw:d3d_device_inner_AddRef 0019F2C8 increasing refcount to 2. 0100:trace:ddraw:d3d_device2_Release iface 0019F2D0. 0100:trace:ddraw:d3d_device_inner_Release 0019F2C8 decreasing refcount to 1. 0100:trace:ddraw:d3d_device_inner_Release Done 0100:trace:d3drm:d3drm_device3_GetDirect3DDevice2 iface 001767E8, d3d_device 0031F120. 0100:trace:ddraw:d3d_device1_QueryInterface iface 0019F2D4, riid {93281501-8cf8-11d0-89ab-00a0c9054129}, out 0031F120. 0100:trace:ddraw:d3d_device_inner_QueryInterface iface 0019F2D8, riid {93281501-8cf8-11d0-89ab-00a0c9054129}, out 0031F120. 0100:trace:ddraw:d3d_device2_AddRef iface 0019F2D0. 0100:trace:ddraw:d3d_device_inner_AddRef 0019F2C8 increasing refcount to 2. 0100:trace:ddraw:d3d_device2_QueryInterface iface 0019F2D0, riid {b0ab3b60-33d7-11d1-a981-00c04fd7b174}, out 0050691C. 0100:trace:ddraw:d3d_device_inner_QueryInterface iface 0019F2D8, riid {b0ab3b60-33d7-11d1-a981-00c04fd7b174}, out 0050691C. 0100:warn:ddraw:d3d_device_inner_QueryInterface {b0ab3b60-33d7-11d1-a981-00c04fd7b174} not implemented, returning E_NOINTERFACE. 0100:trace:ddraw:d3d_device2_Release iface 0019F2D0. 0100:trace:ddraw:d3d_device_inner_Release 0019F2C8 decreasing refcount to 1. 0100:trace:ddraw:d3d_device_inner_Release Done 0100:fixme:d3drm:d3drm_device3_SetBufferCount iface 001767E8, count 2 stub! ...
'{b0ab3b60-33d7-11d1-a981-00c04fd7b174}' -> IDirect3DDevice3
d3drm_device3_GetDirect3DDevice2 -> d3d_device2_QueryInterface -> d3d_device_inner_QueryInterface device->version == 2
The problem starts earlier with 'd3drm3_CreateDeviceFromSurface' call.
Wine source:
https://source.winehq.org/git/wine.git/blob/310019789f7bde12ae3f25f723957c97...
--- snip --- 1615 static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *guid, 1616 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, DWORD flags, IDirect3DRMDevice3 **device) 1617 { 1618 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface); 1619 struct d3drm_device *object; 1620 BOOL use_z_surface; 1621 HRESULT hr; 1622 1623 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, flags %#x, device %p.\n", 1624 iface, debugstr_guid(guid), ddraw, backbuffer, flags, device); 1625 1626 if (!device) 1627 return D3DRMERR_BADVALUE; 1628 *device = NULL; 1629 1630 if (!backbuffer || !ddraw) 1631 return D3DRMERR_BADDEVICE; 1632 1633 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface))) 1634 return hr; 1635 1636 use_z_surface = !(flags & D3DRMDEVICE_NOZBUFFER); 1637 1638 if (SUCCEEDED(hr = d3drm_device_init(object, 3, ddraw, backbuffer, use_z_surface))) 1639 *device = &object->IDirect3DRMDevice3_iface; 1640 else 1641 d3drm_device_destroy(object); 1642 1643 return hr; 1644 } --- snip ---
d3drm_device_init(object, 3, ...)
https://source.winehq.org/git/wine.git/blob/310019789f7bde12ae3f25f723957c97...
--- snip --- 120 HRESULT d3drm_device_init(struct d3drm_device *device, UINT version, IDirectDraw *ddraw, IDirectDrawSurface *surface, 121 BOOL create_z_surface) 122 { 123 DDSCAPS caps = { DDSCAPS_ZBUFFER }; 124 IDirectDrawSurface *ds = NULL; 125 IDirect3DDevice *device1 = NULL; 126 IDirect3DDevice2 *device2 = NULL; 127 IDirect3D2 *d3d2 = NULL; 128 DDSURFACEDESC desc, surface_desc; 129 HRESULT hr; 130 131 device->ddraw = ddraw; 132 IDirectDraw_AddRef(ddraw); 133 IDirect3DRM_AddRef(device->d3drm); 134 device->render_target = surface; 135 IDirectDrawSurface_AddRef(surface); 136 137 desc.dwSize = sizeof(desc); 138 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc); 139 if (FAILED(hr)) 140 return hr; 141 142 if (!(desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) 143 return DDERR_INVALIDCAPS; 144 145 hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds); 146 if (SUCCEEDED(hr)) 147 { 148 create_z_surface = FALSE; 149 IDirectDrawSurface_Release(ds); 150 ds = NULL; 151 } 152 153 if (create_z_surface) 154 { 155 memset(&surface_desc, 0, sizeof(surface_desc)); 156 surface_desc.dwSize = sizeof(surface_desc); 157 surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT; 158 surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; 159 surface_desc.u2.dwZBufferBitDepth = 16; 160 surface_desc.dwWidth = desc.dwWidth; 161 surface_desc.dwHeight = desc.dwHeight; 162 hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &ds, NULL); 163 if (FAILED(hr)) 164 return hr; 165 166 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds); 167 IDirectDrawSurface_Release(ds); 168 if (FAILED(hr)) 169 return hr; 170 } 171 172 if (version == 1) 173 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DRGBDevice, (void **)&device1); 174 else 175 { 176 IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D2, (void**)&d3d2); 177 hr = IDirect3D2_CreateDevice(d3d2, &IID_IDirect3DRGBDevice, surface, &device2); 178 IDirect3D2_Release(d3d2); 179 } 180 if (FAILED(hr)) 181 { 182 IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds); 183 return hr; 184 } 185 186 if (version != 1) 187 { 188 hr = IDirect3DDevice2_QueryInterface(device2, &IID_IDirect3DDevice, (void**)&device1); 189 IDirect3DDevice2_Release(device2); 190 if (FAILED(hr)) 191 { 192 IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds); 193 return hr; 194 } 195 } 196 device->device = device1; 197 device->width = desc.dwWidth; 198 device->height = desc.dwHeight; 199 200 return hr; 201 } --- snip ---
I'm not an expert on this but for me it seems that version == 3 case is not handled here. The code uses IDirect3D2_CreateDevice for all cases != 1 which later leads to the problem that 'IDirect3DDevice3' interface can't be queried by design. It should be using 'IDirect3D3_CreateDevice' for version == 3 case.
$ sha1sum LEGO_Rock_Raiders_Win_Files_EN.7z 7cc3857fb6f1c7063c665ca4e88d62c8fcdadaed LEGO_Rock_Raiders_Win_Files_EN.7z
$ du -sh LEGO_Rock_Raiders_Win_Files_EN.7z 397M LEGO_Rock_Raiders_Win_Files_EN.7z
$ wine --version wine-6.0-rc1-29-g310019789f7
Regards