World of Warplanes calls SetWindowLong(window, GWL_STYLE, WS_POPUP) before calling reset, effectively hiding the window. It does not call SetWindowPos(SWP_FRAMECHANGED), so the effect isn't visible and the game displays fine after the reset. However, after the next mouse click WINPOS_WindowFromPoint skips the window because it doesn't have WS_VISIBLE and returns the desktop window. This in turn triggers a focus loss and d3d9 minimizes the game.
Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
Version 3: Use SW_SHOW instead of SW_SHOWNORMAL to avoid knocking ddraw test windows out of WS_MAXIMIZED state. I originally thought SW_SHOWNORMAL is needed to create a WINDOWPOS structure that matches that of Windows, but that was apparently wrong.
Version 2: Don't check the MoveWindow() WINDOWPOS structure. It differs between Windows versions - Windows 10 17.03 changed the behavior. The message that causes the window to be re-shown is consistent among all versions.
I am quite sure the new Windows behavior breaks a game or two, but I haven't tested my game collection yet... --- dlls/d3d9/tests/d3d9ex.c | 118 +++++++++++++++++++++++++++++++++++++++++++-- dlls/d3d9/tests/device.c | 121 +++++++++++++++++++++++++++++++++++++++++++++-- dlls/wined3d/swapchain.c | 1 + 3 files changed, 232 insertions(+), 8 deletions(-)
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c index 648d17bac4..c965af7264 100644 --- a/dlls/d3d9/tests/d3d9ex.c +++ b/dlls/d3d9/tests/d3d9ex.c @@ -2468,6 +2468,7 @@ struct message enum message_window window; BOOL check_wparam; WPARAM expect_wparam; + WINDOWPOS *store_wp; };
static const struct message *expect_messages; @@ -2516,6 +2517,9 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM "Got unexpected wparam %lx for message %x, expected %lx.\n", wparam, message, expect_messages->expect_wparam);
+ if (expect_messages->store_wp) + *expect_messages->store_wp = *(WINDOWPOS *)lparam; + ++expect_messages; } } @@ -2583,9 +2587,10 @@ static void test_wndproc(void) D3DDISPLAYMODE d3ddm; DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0; DEVMODEW devmode; - LONG change_ret; + LONG change_ret, device_style; BOOL ret; IDirect3D9Ex *d3d9ex; + WINDOWPOS windowpos;
static const struct message create_messages[] = { @@ -2678,16 +2683,59 @@ static void test_wndproc(void) /* WM_SIZE(SIZE_MAXIMIZED) is unreliable on native. */ {0, 0, FALSE, 0}, }; - static const struct + struct message mode_change_messages[] = + { + {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0}, + {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0}, + {WM_SIZE, DEVICE_WINDOW, FALSE, 0}, + /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is + * differs between Wine and Windows. */ + /* TODO 2: Windows sends a second WM_WINDOWPOSCHANGING(SWP_NOMOVE | SWP_NOSIZE + * | SWP_NOACTIVATE) in this situation, suggesting a difference in their ShowWindow + * implementation. This SetWindowPos call could in theory affect the Z order. Wine's + * ShowWindow does not send such a message because the window is already visible. */ + {0, 0, FALSE, 0}, + }; + struct message mode_change_messages_hidden[] = + { + {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0}, + {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0}, + {WM_SIZE, DEVICE_WINDOW, FALSE, 0}, + {WM_SHOWWINDOW, DEVICE_WINDOW, FALSE, 0}, + {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0, &windowpos}, + {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0}, + /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is + * differs between Wine and Windows. */ + {0, 0, FALSE, 0}, + }; + static const struct message mode_change_messages_nowc[] = + { + {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0}, + {0, 0, FALSE, 0}, + }; + struct { DWORD create_flags; const struct message *focus_loss_messages; + const struct message *mode_change_messages, *mode_change_messages_hidden; BOOL iconic; } tests[] = { - {0, focus_loss_messages, TRUE}, - {CREATE_DEVICE_NOWINDOWCHANGES, focus_loss_messages_nowc, FALSE}, + { + 0, + focus_loss_messages, + mode_change_messages, + mode_change_messages_hidden, + TRUE + }, + { + CREATE_DEVICE_NOWINDOWCHANGES, + focus_loss_messages_nowc, + mode_change_messages_nowc, + mode_change_messages_nowc, + FALSE + }, };
hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex); @@ -3051,6 +3099,68 @@ static void test_wndproc(void) skip("Failed to create a D3D device, skipping tests.\n"); goto done; } + filter_messages = NULL; + flush_events(); + + device_desc.width = user32_width; + device_desc.height = user32_height; + + expect_messages = tests[i].mode_change_messages; + filter_messages = focus_window; + hr = reset_device(device, &device_desc); + ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr); + filter_messages = NULL; + + /* The WINDOWPOS structure passed to the first WM_WINDOWPOSCHANGING differs between windows versions. + * Prior to Win10 17.03 it is consistent with a MoveWindow(0, 0, width, height) call. Since Windows + * 10 17.03 it has x = 0, y = 0, width = 0, height = 0, flags = SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE + * | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER (0x1837). Visually + * it is clear that the window has not been resized. In previous Windows version the window is resized. */ + + flush_events(); + 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); + + /* World of Warplanes hides the window by removing WS_VISIBLE and expects Reset() to show it again. */ + device_style = GetWindowLongA(device_window, GWL_STYLE); + SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE); + + flush_events(); + device_desc.width = d3d_width; + device_desc.height = d3d_height; + memset(&windowpos, 0, sizeof(windowpos)); + + expect_messages = tests[i].mode_change_messages_hidden; + filter_messages = focus_window; + hr = reset_device(device, &device_desc); + ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr); + filter_messages = NULL; + + flush_events(); + 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); + + if (!(tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)) + { + ok(windowpos.hwnd == device_window && !windowpos.hwndInsertAfter + && !windowpos.x && !windowpos.y && !windowpos.cx && !windowpos.cy + && windowpos.flags == (SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE), + "Got unexpected WINDOWPOS hwnd=%p, insertAfter=%p, x=%d, y=%d, cx=%d, cy=%d, flags=%x\n", + windowpos.hwnd, windowpos.hwndInsertAfter, windowpos.x, windowpos.y, windowpos.cx, + windowpos.cy, windowpos.flags); + } + + device_style = GetWindowLongA(device_window, GWL_STYLE); + if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES) + { + todo_wine ok(!(device_style & WS_VISIBLE), "Expected the device window to be hidden, i=%u.\n", i); + ShowWindow(device_window, SW_MINIMIZE); + ShowWindow(device_window, SW_RESTORE); + } + else + { + ok(device_style & WS_VISIBLE, "Expected the device window to be visible, i=%u.\n", i); + }
proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA); ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 82ced8372b..388cda1d7a 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -3401,6 +3401,7 @@ struct message enum message_window window; BOOL check_wparam; WPARAM expect_wparam; + WINDOWPOS *store_wp; };
static const struct message *expect_messages; @@ -3449,6 +3450,9 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM "Got unexpected wparam %lx for message %x, expected %lx.\n", wparam, message, expect_messages->expect_wparam);
+ if (expect_messages->store_wp) + *expect_messages->store_wp = *(WINDOWPOS *)lparam; + ++expect_messages; } } @@ -3517,8 +3521,9 @@ static void test_wndproc(void) D3DDISPLAYMODE d3ddm; DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0; DEVMODEW devmode; - LONG change_ret; + LONG change_ret, device_style; BOOL ret; + WINDOWPOS windowpos;
static const struct message create_messages[] = { @@ -3631,16 +3636,61 @@ static void test_wndproc(void) /* WM_SIZE(SIZE_MAXIMIZED) is unreliable on native. */ {0, 0, FALSE, 0}, }; - static const struct + struct message mode_change_messages[] = + { + {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0}, + {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0}, + {WM_SIZE, DEVICE_WINDOW, FALSE, 0}, + /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is + * differs between Wine and Windows. */ + /* TODO 2: Windows sends a second WM_WINDOWPOSCHANGING(SWP_NOMOVE | SWP_NOSIZE + * | SWP_NOACTIVATE) in this situation, suggesting a difference in their ShowWindow + * implementation. This SetWindowPos call could in theory affect the Z order. Wine's + * ShowWindow does not send such a message because the window is already visible. */ + {0, 0, FALSE, 0}, + }; + struct message mode_change_messages_hidden[] = + { + {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0}, + {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0}, + {WM_SIZE, DEVICE_WINDOW, FALSE, 0}, + {WM_SHOWWINDOW, DEVICE_WINDOW, FALSE, 0}, + {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0, &windowpos}, + {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0}, + /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is + * differs between Wine and Windows. */ + {0, 0, FALSE, 0}, + }; + static const struct message mode_change_messages_nowc[] = + { + {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0}, + {0, 0, FALSE, 0}, + }; + struct { DWORD create_flags; const struct message *focus_loss_messages, *reactivate_messages; + const struct message *mode_change_messages, *mode_change_messages_hidden; BOOL iconic; } tests[] = { - {0, focus_loss_messages, reactivate_messages, TRUE}, - {CREATE_DEVICE_NOWINDOWCHANGES, focus_loss_messages_nowc, reactivate_messages_nowc, FALSE}, + { + 0, + focus_loss_messages, + reactivate_messages, + mode_change_messages, + mode_change_messages_hidden, + TRUE + }, + { + CREATE_DEVICE_NOWINDOWCHANGES, + focus_loss_messages_nowc, + reactivate_messages_nowc, + mode_change_messages_nowc, + mode_change_messages_nowc, + FALSE + }, };
d3d9 = Direct3DCreate9(D3D_SDK_VERSION); @@ -4026,11 +4076,74 @@ static void test_wndproc(void) skip("Failed to create a D3D device, skipping tests.\n"); goto done; } + filter_messages = NULL; + flush_events(); + + device_desc.width = user32_width; + device_desc.height = user32_height; + + expect_messages = tests[i].mode_change_messages; + filter_messages = focus_window; + hr = reset_device(device, &device_desc); + ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr); + filter_messages = NULL; + + /* The WINDOWPOS structure passed to the first WM_WINDOWPOSCHANGING differs between windows versions. + * Prior to Win10 17.03 it is consistent with a MoveWindow(0, 0, width, height) call. Since Windows + * 10 17.03 it has x = 0, y = 0, width = 0, height = 0, flags = SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE + * | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER (0x1837). Visually + * it is clear that the window has not been resized. In previous Windows version the window is resized. */ + + flush_events(); + 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); + + /* World of Warplanes hides the window by removing WS_VISIBLE and expects Reset() to show it again. */ + device_style = GetWindowLongA(device_window, GWL_STYLE); + SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE); + + flush_events(); + device_desc.width = d3d_width; + device_desc.height = d3d_height; + memset(&windowpos, 0, sizeof(windowpos)); + + expect_messages = tests[i].mode_change_messages_hidden; + filter_messages = focus_window; + hr = reset_device(device, &device_desc); + ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr); + filter_messages = NULL; + + flush_events(); + 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); + + if (!(tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)) + { + ok(windowpos.hwnd == device_window && !windowpos.hwndInsertAfter + && !windowpos.x && !windowpos.y && !windowpos.cx && !windowpos.cy + && windowpos.flags == (SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE), + "Got unexpected WINDOWPOS hwnd=%p, insertAfter=%p, x=%d, y=%d, cx=%d, cy=%d, flags=%x\n", + windowpos.hwnd, windowpos.hwndInsertAfter, windowpos.x, windowpos.y, windowpos.cx, + windowpos.cy, windowpos.flags); + } + + device_style = GetWindowLongA(device_window, GWL_STYLE); + if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES) + { + todo_wine ok(!(device_style & WS_VISIBLE), "Expected the device window to be hidden, i=%u.\n", i); + ShowWindow(device_window, SW_MINIMIZE); + ShowWindow(device_window, SW_RESTORE); + } + else + { + ok(device_style & WS_VISIBLE, "Expected the device window to be visible, i=%u.\n", i); + }
proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA); ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, i=%u.\n", (LONG_PTR)test_proc, i);
+ filter_messages = focus_window; ref = IDirect3DDevice9_Release(device); ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index e23e99b67b..dd3655f61c 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1429,6 +1429,7 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha device->filter_messages = TRUE;
MoveWindow(swapchain->device_window, 0, 0, width, height, TRUE); + ShowWindow(swapchain->device_window, SW_SHOW);
device->filter_messages = filter_messages; }
Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
Version 3: Show the device window before creating a device. The previous test was hiding it to avoid stray messages. Because of this MoveWindow did not create a WM_SIZE message. ShowWindow(SW_SHOWNORMAL) did, making the test pass for the wrong reason.
Of course creating the device shows the window, but before the test hides it it minimizes it, so the device renders to a minimized window. This is probably a bug in Wine, but it's a matter for a different patch.
Version 2: Do not check the contents of the MoveWindow() WINDOWPOS structure. --- dlls/d3d8/tests/device.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 9cebd17e2d..94b3e2e407 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -2435,6 +2435,7 @@ struct message enum message_window window; BOOL check_wparam; WPARAM expect_wparam; + WINDOWPOS *store_wp; };
static const struct message *expect_messages; @@ -2483,6 +2484,9 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM "Got unexpected wparam %lx for message %x, expected %lx.\n", wparam, message, expect_messages->expect_wparam);
+ if (expect_messages->store_wp) + *expect_messages->store_wp = *(WINDOWPOS *)lparam; + ++expect_messages; } } @@ -2549,8 +2553,9 @@ static void test_wndproc(void) D3DDISPLAYMODE d3ddm; DWORD d3d_width = 0, d3d_height = 0, user32_width = 0, user32_height = 0; DEVMODEW devmode; - LONG change_ret; + LONG change_ret, device_style; BOOL ret; + WINDOWPOS windowpos;
static const struct message create_messages[] = { @@ -2649,6 +2654,31 @@ static void test_wndproc(void) {WM_SIZE, FOCUS_WINDOW, TRUE, SIZE_MAXIMIZED}, {0, 0, FALSE, 0}, }; + struct message mode_change_messages[] = + { + {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0}, + {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0}, + {WM_SIZE, DEVICE_WINDOW, FALSE, 0}, + /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is + * differs between Wine and Windows. */ + /* TODO 2: Windows sends a second WM_WINDOWPOSCHANGING(SWP_NOMOVE | SWP_NOSIZE + * | SWP_NOACTIVATE) in this situation, suggesting a difference in their ShowWindow + * implementation. This SetWindowPos call could in theory affect the Z order. Wine's + * ShowWindow does not send such a message because the window is already visible. */ + {0, 0, FALSE, 0}, + }; + struct message mode_change_messages_hidden[] = + { + {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0}, + {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0}, + {WM_SIZE, DEVICE_WINDOW, FALSE, 0}, + {WM_SHOWWINDOW, DEVICE_WINDOW, FALSE, 0}, + {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0, &windowpos}, + {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0}, + /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is + * differs between Wine and Windows. */ + {0, 0, FALSE, 0}, + };
d3d8 = Direct3DCreate8(D3D_SDK_VERSION); ok(!!d3d8, "Failed to create a D3D object.\n"); @@ -3010,13 +3040,63 @@ static void test_wndproc(void)
ref = IDirect3DDevice8_Release(device); ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref); + filter_messages = NULL; + + ShowWindow(device_window, SW_RESTORE); + SetForegroundWindow(focus_window); + flush_events();
+ filter_messages = focus_window; device_desc.device_window = device_window; if (!(device = create_device(d3d8, focus_window, &device_desc))) { skip("Failed to create a D3D device, skipping tests.\n"); goto done; } + filter_messages = NULL; + flush_events(); + + device_desc.width = user32_width; + device_desc.height = user32_height; + + expect_messages = mode_change_messages; + filter_messages = focus_window; + hr = reset_device(device, &device_desc); + ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr); + filter_messages = NULL; + + flush_events(); + 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); + + /* World of Warplanes hides the window by removing WS_VISIBLE and expects Reset() to show it again. */ + device_style = GetWindowLongA(device_window, GWL_STYLE); + SetWindowLongA(device_window, GWL_STYLE, device_style & ~WS_VISIBLE); + + flush_events(); + device_desc.width = d3d_width; + device_desc.height = d3d_height; + memset(&windowpos, 0, sizeof(windowpos)); + + expect_messages = mode_change_messages_hidden; + filter_messages = focus_window; + hr = reset_device(device, &device_desc); + ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr); + filter_messages = NULL; + + flush_events(); + ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n", + expect_messages->message, expect_messages->window); + + ok(windowpos.hwnd == device_window && !windowpos.hwndInsertAfter + && !windowpos.x && !windowpos.y && !windowpos.cx && !windowpos.cy + && windowpos.flags == (SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE), + "Got unexpected WINDOWPOS hwnd=%p, insertAfter=%p, x=%d, y=%d, cx=%d, cy=%d, flags=%x\n", + windowpos.hwnd, windowpos.hwndInsertAfter, windowpos.x, windowpos.y, windowpos.cx, + windowpos.cy, windowpos.flags); + + device_style = GetWindowLongA(device_window, GWL_STYLE); + ok(device_style & WS_VISIBLE, "Expected the device window to be visible.\n");
proc = SetWindowLongPtrA(focus_window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA); ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx.\n", (LONG_PTR)test_proc);
Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
This avoids a test failure for me on Wine with my new Nvidia Geforce GTX 1060: device.c:9404: Test failed: Expected available texture memory to decrease during texture creation. device.c:9406: Test failed: Expected a video memory difference of at least 40 MB, got 0 MB.
Note that I don't have Windows yet on my new machine, so I cannot compare the behavior of d3d9 with too much video memory than it can report. Ignore this patch for now if that concerns you. --- dlls/d3d9/tests/device.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 388cda1d7a..75e3b3e4ec 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -25,6 +25,7 @@ #define WINVER 0x0602 /* for CURSOR_SUPPRESSED */ #define COBJMACROS #include <d3d9.h> +#include <limits.h> #include "wine/test.h"
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) @@ -9389,6 +9390,12 @@ static void test_vidmem_accounting(void) }
vidmem_start = IDirect3DDevice9_GetAvailableTextureMem(device); + if (vidmem_start == UINT_MAX) + { + skip("GPU has more video memory than can be reported, skipping vidmem decrease test.\n"); + goto cleanup; + } + memset(textures, 0, sizeof(textures)); for (i = 0; i < ARRAY_SIZE(textures); i++) { @@ -9412,6 +9419,7 @@ static void test_vidmem_accounting(void) IDirect3DTexture9_Release(textures[i]); }
+cleanup: refcount = IDirect3DDevice9_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); IDirect3D9_Release(d3d9);