---
See the added comment for details what is going on.
From: Stefan Dösinger stefan@codeweavers.com
---
See the added comment for details what is going on. --- dlls/d3d9/tests/device.c | 60 ++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 20 deletions(-)
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 8ab52c7d5e4..4e10e8ac451 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -4752,11 +4752,13 @@ done: static void test_reset_fullscreen(void) { struct device_desc device_desc; - D3DDISPLAYMODE d3ddm, d3ddm2; unsigned int mode_count, i; IDirect3DDevice9 *device; + D3DDISPLAYMODE d3ddm; WNDCLASSEXA wc = {0}; IDirect3D9 *d3d; + D3DFORMAT fmt; + RECT r1, r2; HRESULT hr; ATOM atom; static const struct message messages[] = @@ -4795,48 +4797,66 @@ static void test_reset_fullscreen(void) goto cleanup; }
+ IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm); + fmt = d3ddm.Format; + mode_count = IDirect3D9_GetAdapterModeCount(d3d, D3DADAPTER_DEFAULT, fmt); + for (i = 0; i < mode_count; ++i) + { + hr = IDirect3D9_EnumAdapterModes(d3d, D3DADAPTER_DEFAULT, fmt, i, &d3ddm); + ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#lx.\n", hr); + + if (d3ddm.Width != registry_mode.dmPelsWidth || d3ddm.Height != registry_mode.dmPelsHeight) + break; + } + if (i == mode_count) + { + skip("Could not find a suitable display mode.\n"); + goto cleanup; + } + /* * Switch to fullscreen mode. * This will force the window to be shown and will cause the WM_ACTIVATEAPP * message to be sent. */ - device_desc.width = registry_mode.dmPelsWidth; - device_desc.height = registry_mode.dmPelsHeight; + device_desc.width = d3ddm.Width; + device_desc.height = d3ddm.Height; device_desc.device_window = device_window; device_desc.flags = CREATE_DEVICE_FULLSCREEN; ok(SUCCEEDED(reset_device(device, &device_desc)), "Failed to reset device.\n");
+ /* The Linux gitlab CI machines have a window manager that insists on growing the + * window to the size of the original display mode, even if the current mode is + * smaller. We don't learn about this until we process messages, but then we + * receive a WM_SIZE message after d3d9 stopped filtering. To dodge the issue, + * switch to the original mode when testing for WM_SIZE, but double check that the + * window size was changed. */ + GetWindowRect(device_window, &r1); + flush_events(); ok(expect_messages->message == 0, "Expected to receive message %#x.\n", expect_messages->message); expect_messages = NULL;
- IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT, &d3ddm); - mode_count = IDirect3D9_GetAdapterModeCount(d3d, D3DADAPTER_DEFAULT, d3ddm.Format); - for (i = 0; i < mode_count; ++i) - { - hr = IDirect3D9_EnumAdapterModes(d3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2); - ok(SUCCEEDED(hr), "Failed to enumerate display mode, hr %#lx.\n", hr); - - if (d3ddm2.Width != d3ddm.Width || d3ddm2.Height != d3ddm.Height) - break; - } - if (i == mode_count) - { - skip("Could not find a suitable display mode.\n"); - goto cleanup; - } + /* This is what the evil WM does to us: Resize the window behind our back. */ + GetWindowRect(device_window, &r2); + todo_wine_if(!EqualRect(&r1, &r2)) + ok(EqualRect(&r1, &r2), "Window rect changed during event flush: %s -> %s.\n", + wine_dbgstr_rect(&r1), wine_dbgstr_rect(&r2));
wm_size_received = 0;
/* Fullscreen mode change. */ - device_desc.width = d3ddm2.Width; - device_desc.height = d3ddm2.Height; + device_desc.width = registry_mode.dmPelsWidth; + device_desc.height = registry_mode.dmPelsHeight; device_desc.device_window = device_window; device_desc.flags = CREATE_DEVICE_FULLSCREEN; ok(SUCCEEDED(reset_device(device, &device_desc)), "Failed to reset device.\n");
flush_events(); ok(!wm_size_received, "Received unexpected WM_SIZE message.\n"); + GetWindowRect(device_window, &r2); + ok(!EqualRect(&r1, &r2), "Window rectangles before and after mode change are equal: %s\n", + wine_dbgstr_rect(&r1));
cleanup: if (device) IDirect3DDevice9_Release(device);
From: Stefan Dösinger stefan@codeweavers.com
d3d8 is not affected in this way because it does not call flush_events() between focus loss and re-gain. --- dlls/d3d9/tests/device.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 4e10e8ac451..a1d587f0fef 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -4228,6 +4228,18 @@ static void test_wndproc(void) } flush_events();
+ if (!(tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)) + { + /* The window manager on Gitlab CI insists on restoring the device window for some reason. + * In this case we might not receive WM_WINDOWPOSCHANGING on the device window because nothing + * is being changed on focus gain. + * + * Wine's internal status is being updated while processing messages (the flush_events above). */ + ret = IsIconic(device_window); + todo_wine_if (!ret) + ok(ret, "Expected the device window to still be iconic.\n"); + } + /* I have to minimize and restore the focus window, otherwise native d3d9 fails * device::reset with D3DERR_DEVICELOST. This does not happen when the window * restore is triggered by the user. */ @@ -4239,7 +4251,8 @@ static void test_wndproc(void) flush_events(); SetForegroundWindow(focus_window); flush_events(); /* WM_WINDOWPOSCHANGING etc arrive after SetForegroundWindow returns. */ - ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n", + todo_wine_if (!ret) + ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n", expect_messages->message, expect_messages->window, i); expect_messages = NULL;
From: Stefan Dösinger stefan@codeweavers.com
---
This fixes failures on the gitlab-debian-32/64 machines. --- dlls/d3d9/tests/device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index a1d587f0fef..4ab0677ff7e 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -6613,7 +6613,9 @@ static void test_occlusion_query(void)
hr = IDirect3DDevice9_BeginScene(device); ok(hr == D3D_OK, "Failed to begin scene, hr %#lx.\n", hr); - for (i = 0; i < 50000; ++i) + /* Too many (~43k) redundant query cycles will break the occlusion query on Nvidia's + * Linux blob. */ + for (i = 0; i < 40000; ++i) { hr = IDirect3DQuery9_Issue(query, D3DISSUE_BEGIN); ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
+ /* This is what the evil WM does to us: Resize the window behind our back. */
I think gitlab CI is running fvwm2 instead of evilwm...
I happen to be rather fond of fvwm, but IIRC it does have the issue of not updating it's screen size in response to RandR mode changes, which I guess is what we're running into here. I think RandR support is supposed to be improved in fvwm3, fwiw.
There are a few other things that need refinement here. It doesn't reliably fix the WM_SIZE failure on my system with fvwm 2.7.0 and gitlab CI still has some other issues. I'll try to mark this as draft for now if I find the button for it.