https://bugs.winehq.org/show_bug.cgi?id=54659
Bug ID: 54659 Summary: d3d8:device & d3d9:device sometimes get floating point underflow in GenerateRampFromGamma() in Wine Product: Wine Version: unspecified Hardware: x86-64 OS: Linux Status: NEW Severity: normal Priority: P2 Component: d3d Assignee: wine-bugs@winehq.org Reporter: fgouget@codeweavers.com Distribution: ---
d3d8:device & d3d9:device sometimes get an floating point underflow exception in GenerateRampFromGamma() in Wine:
d3d8:device start dlls/d3d8/tests/device.c Unhandled exception: floating point underflow in 32-bit code (0x7e91438f). [...] Backtrace: =>0 0x7e91438f in libm.so.6 (+0x2538f) (0x0069ef68) 1 0x7e922d3b in libm.so.6 (+0x33d3b) (0x0069ef68) 2 0x7e55c181 GenerateRampFromGamma+0x51(ramp=00197C4C, gamma=0.000300) [Z:\home\winetest\tools\testbot\var\wine\dlls\winex11.drv\xvidmode.c:336] in winex11.so (0x0069ef68) 3 0x7e55c9b2 X11DRV_XF86VM_GetGammaRamp+0x60(ramp=<internal error>) [Z:\home\winetest\tools\testbot\var\wine\dlls\winex11.drv\xvidmode.c:519] in winex11.so (0x0069ef68) 4 0x7e55c9b2 X11DRV_GetDeviceGammaRamp+0x82(dev=<couldn't compute location>, ramp=<couldn't compute location>) [Z:\home\winetest\tools\testbot\var\wine\dlls\winex11.drv\xvidmode.c:569] in winex11.so (0x0069ef68) 5 0x7ea32408 NtGdiGetDeviceGammaRamp+0x88(hdc=<couldn't compute location>, ptr=<couldn't compute location>) [Z:\home\winetest\tools\testbot\var\wine\dlls\win32u\dc.c:1247] in win32u.so (0x0069efb8) 6 0x64a8d74c NtGdiGetDeviceGammaRamp+0x2c(hdc=<couldn't compute location>, ptr=<couldn't compute location>) [Z:\home\winetest\tools\testbot\var\wine\dlls\win32u\wrappers.c:280] in win32u (0x0069efe8) 7 0x6ccf9d3d wined3d_output_get_gamma_ramp+0x4d(output=00140E10, ramp=00197C4C) [Z:\home\winetest\tools\testbot\var\wine\dlls\wined3d\directx.c:1741] in wined3d (0x0069f028) 8 0x6cd5fcb0 wined3d_swapchain_get_gamma_ramp+0x30(swapchain=00197C30, ramp=00197C4C) [Z:\home\winetest\tools\testbot\var\wine\dlls\wined3d\swapchain.c:385] in wined3d (0x0069f058) 9 0x6cd61190 wined3d_swapchain_init+0x3c0(swapchain=<register EBX not accessible in this frame>, device=<register EDI not accessible in this frame>, desc=<internal error>, state_parent=00140D5C, parent=00140D50, parent_ops=67CDE7D4, swapchain_ops=6CE6933C) [Z:\home\winetest\tools\testbot\var\wine\dlls\wined3d\swapchain.c:1633] in wined3d (0x0069f168) 10 0x6cc8d9f3 adapter_gl_create_swapchain+0x73(device=0017B3E8, desc=0069F2BC, state_parent=00140D5C, parent=00140D50, parent_ops=67CDE7D4, swapchain=0069F1FC) [Z:\home\winetest\tools\testbot\var\wine\dlls\wined3d\adapter_gl.c:4701] in wined3d (0x0069f1b8) 11 0x6cd5fdd1 wined3d_swapchain_create+0x41(device=0017B3E8, desc=0069F2BC, state_parent=00140D5C, parent=00140D50, parent_ops=67CDE7D4, swapchain=00140D58) [Z:\home\winetest\tools\testbot\var\wine\dlls\wined3d\swapchain.c:1724] in wined3d (0x0069f208) 12 0x67ccfe84 swapchain_init+0x48(swap_interval=<internal error>, desc=<internal error>, device=<internal error>, swapchain=<internal error>) [Z:\home\winetest\tools\testbot\var\wine\dlls\d3d8\swapchain.c:180] in d3d8 (0x0069f248) 13 0x67ccfe84 d3d8_swapchain_create+0x84(device=001468F0, desc=0069F2BC, swap_interval=0xffffffff, swapchain=0069F290) [Z:\home\winetest\tools\testbot\var\wine\dlls\d3d8\swapchain.c:199] in d3d8 (0x0069f248) 14 0x67ccc467 device_init+0x217(device=001468F0, parent=00140A90, wined3d=00140AB0, adapter=0, device_type=D3DDEVTYPE_HAL, focus_window=0003004A, flags=0x42, parameters=0069F53C) [Z:\home\winetest\tools\testbot\var\wine\dlls\d3d8\device.c:3744] in d3d8 (0x0069f478) 15 0x67ccd649 d3d8_CreateDevice+0xa9(iface=<couldn't compute location>, adapter=<couldn't compute location>, device_type=<couldn't compute location>, focus_window=<couldn't compute location>, flags=<couldn't compute location>, parameters=<couldn't compute location>, device=<couldn't compute location>) [Z:\home\winetest\tools\testbot\var\wine\dlls\d3d8\directx.c:438] in d3d8 (0x0069f4e8) 16 0x004010ce in d3d8_test (+0x10ce) (0x0069f588) ...
This does not happen in the nightly Wine test runs but impacted at least two merge requests: * MR2072, repeatedly * MR2217, repeatedly
There are three immediate questions: * Where does the 0.000300 gamma come from? I don't think such a value makes sense so I suspect it's caused by a bug somewhere.
* Should xvidmode.c's GenerateRampFromGamma() crash in case of underflow (or overflow for that matter)? If not, ComputeGammaFromRamp() should probably be fixed too. Which other functions have the same issue? (not just in xvidmode.c)
* By default underflows don't cause exceptions. So which piece of code in d3d8:device does a _control87(0, _EM_UNDERFLOW) ?
Then, why does this failure not happen more often? The debian11 VM ran the tests multiple times in a row to test various locales: en -> success ar:MA -> success de -> success fr -> underflow he:IL -> underflow hi:IN -> underflow ja:JP -> underflow zh:CN -> underflow
While the wineprefix is recreated for each test, all the tests run on the same X server session. So my theory is that one of the tests in the first three runs progressively degraded the gamma at the X level, such that all the tests that followed got a bad gamma from the X server and crashed. Furthermore note that the first plain 32-bit run ran the full Wine test suite. That may have been a factor too.
MR2217 caused the following tests to run so the guilty party should be among them: d3d8:device d3d9:device ddraw:ddraw1 ddraw:ddraw2 ddraw:ddraw4 ddraw:ddraw7
That explains why this failure does not happen in the nightly Wine test runs: each is done after restoring the VM to a clean state. Similarly, other merge requests may run fewer tests so that the gamma does not get degraded that much.
That leaves a mystery though: I don't get this issue on my desktop (fg-deb64) despite running the tests every night and not ever restarting the X server (thankfully!). Maybe this gamma issue is caused by a bug that only happens with the VM environment (likely QXL GPU or dual screen configuration, such that it does not happen on single-screen Intel GPUs)?