[PATCH v2 6/7] dxgi/tests: Test display mode restoration.
Zhiyi Zhang
zzhang at codeweavers.com
Fri Oct 30 01:49:00 CDT 2020
Mostly to test that when doing mode restoration, all display outputs get restored to their display
settings in the registry, not just one output gets restored.
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/dxgi/tests/dxgi.c | 427 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 427 insertions(+)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index 43c4247dc2a..4d9677b3762 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -134,6 +134,77 @@ static void get_virtual_rect(RECT *rect)
rect->bottom = rect->top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
+static BOOL equal_mode_rect(const DEVMODEW *mode1, const DEVMODEW *mode2)
+{
+ return mode1->dmPosition.x == mode2->dmPosition.x
+ && mode1->dmPosition.y == mode2->dmPosition.y
+ && mode1->dmPelsWidth == mode2->dmPelsWidth
+ && mode1->dmPelsHeight == mode2->dmPelsHeight;
+}
+
+/* Free original_modes after finished using it */
+static BOOL save_display_modes(DEVMODEW **original_modes, unsigned int *display_count)
+{
+ unsigned int number, size = 2, count = 0, index = 0;
+ DISPLAY_DEVICEW display_device;
+ DEVMODEW *modes, *tmp;
+
+ if (!(modes = heap_alloc(size * sizeof(*modes))))
+ return FALSE;
+
+ display_device.cb = sizeof(display_device);
+ while (EnumDisplayDevicesW(NULL, index++, &display_device, 0))
+ {
+ /* Skip software devices */
+ if (swscanf(display_device.DeviceName, L"\\\\.\\DISPLAY%u", &number) != 1)
+ continue;
+
+ if (!(display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
+ continue;
+
+ if (count >= size)
+ {
+ size *= 2;
+ if (!(tmp = heap_realloc(modes, size * sizeof(*modes))))
+ {
+ heap_free(modes);
+ return FALSE;
+ }
+ modes = tmp;
+ }
+
+ memset(&modes[count], 0, sizeof(modes[count]));
+ modes[count].dmSize = sizeof(modes[count]);
+ if (!EnumDisplaySettingsW(display_device.DeviceName, ENUM_CURRENT_SETTINGS, &modes[count]))
+ {
+ heap_free(modes);
+ return FALSE;
+ }
+
+ lstrcpyW(modes[count++].dmDeviceName, display_device.DeviceName);
+ }
+
+ *original_modes = modes;
+ *display_count = count;
+ return TRUE;
+}
+
+static BOOL restore_display_modes(DEVMODEW *modes, unsigned int count)
+{
+ unsigned int index;
+ LONG ret;
+
+ for (index = 0; index < count; ++index)
+ {
+ ret = ChangeDisplaySettingsExW(modes[index].dmDeviceName, &modes[index], NULL,
+ CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
+ if (ret != DISP_CHANGE_SUCCESSFUL)
+ return FALSE;
+ }
+ ret = ChangeDisplaySettingsExW(NULL, NULL, NULL, 0, NULL);
+ return ret == DISP_CHANGE_SUCCESSFUL;
+}
+
/* try to make sure pending X events have been processed before continuing */
static void flush_events(void)
{
@@ -6897,6 +6968,360 @@ static void test_colour_space_support(IUnknown *device, BOOL is_d3d12)
ok(ref_count == !is_d3d12, "Factory has %u references left.\n", ref_count);
}
+static void test_mode_change(IUnknown *device, BOOL is_d3d12)
+{
+ unsigned int user32_width = 0, user32_height = 0, d3d_width = 0, d3d_height = 0;
+ unsigned int display_count = 0, mode_idx = 0, adapter_idx, output_idx;
+ DEVMODEW *original_modes = NULL, old_devmode, devmode, devmode2;
+ DXGI_SWAP_CHAIN_DESC swapchain_desc, swapchain_desc2;
+ IDXGIOutput *output, *second_output = NULL;
+ WCHAR second_monitor_name[CCHDEVICENAME];
+ IDXGISwapChain *swapchain, *swapchain2;
+ DXGI_OUTPUT_DESC output_desc;
+ IDXGIAdapter *adapter;
+ IDXGIFactory *factory;
+ BOOL fullscreen, ret;
+ LONG change_ret;
+ ULONG refcount;
+ HRESULT hr;
+
+ memset(&devmode, 0, sizeof(devmode));
+ devmode.dmSize = sizeof(devmode);
+ ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ ok(equal_mode_rect(&devmode, ®istry_mode), "Got a different mode.\n");
+ ret = EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &devmode);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ ok(equal_mode_rect(&devmode, ®istry_mode), "Got a different mode.\n");
+
+ while (EnumDisplaySettingsW(NULL, mode_idx++, &devmode))
+ {
+ if (devmode.dmPelsWidth == registry_mode.dmPelsWidth
+ && devmode.dmPelsHeight == registry_mode.dmPelsHeight)
+ continue;
+
+ if (!d3d_width && !d3d_height)
+ {
+ d3d_width = devmode.dmPelsWidth;
+ d3d_height = devmode.dmPelsHeight;
+ continue;
+ }
+
+ if (devmode.dmPelsWidth == d3d_width && devmode.dmPelsHeight == d3d_height)
+ continue;
+
+ user32_width = devmode.dmPelsWidth;
+ user32_height = devmode.dmPelsHeight;
+ break;
+ }
+ if (!user32_width || !user32_height)
+ {
+ skip("Failed to find three different display modes for the primary output.\n");
+ return;
+ }
+
+ ret = save_display_modes(&original_modes, &display_count);
+ ok(ret, "Failed to save original display modes.\n");
+
+ get_factory(device, is_d3d12, &factory);
+
+ /* Test that no mode restorations if no mode changes actually happened */
+ change_ret = ChangeDisplaySettingsW(&devmode, CDS_UPDATEREGISTRY | CDS_NORESET);
+ ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsW failed with %d.\n", change_ret);
+
+ swapchain_desc.BufferDesc.Width = registry_mode.dmPelsWidth;
+ swapchain_desc.BufferDesc.Height = registry_mode.dmPelsHeight;
+ swapchain_desc.BufferDesc.RefreshRate.Numerator = 60;
+ swapchain_desc.BufferDesc.RefreshRate.Denominator = 1;
+ swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+ swapchain_desc.SampleDesc.Count = 1;
+ swapchain_desc.SampleDesc.Quality = 0;
+ swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapchain_desc.BufferCount = is_d3d12 ? 2 : 1;
+ swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
+ swapchain_desc.Windowed = TRUE;
+ swapchain_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD;
+ swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+
+ hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain);
+ ok(hr == S_OK, "CreateSwapChain failed, hr %#x.\n", hr);
+ refcount = IDXGISwapChain_Release(swapchain);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+
+ memset(&devmode2, 0, sizeof(devmode2));
+ devmode2.dmSize = sizeof(devmode2);
+ ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ ok(equal_mode_rect(&devmode2, ®istry_mode), "Got a different mode.\n");
+ ret = restore_display_modes(original_modes, display_count);
+ ok(ret, "Failed to restore display modes.\n");
+
+ /* If current display settings are different than the display settings in registry before
+ * calling SetFullscreenState() */
+ change_ret = ChangeDisplaySettingsW(&devmode, CDS_UPDATEREGISTRY | CDS_NORESET);
+ ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsW failed with %d.\n", change_ret);
+
+ hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain);
+ ok(hr == S_OK, "CreateSwapChain failed, hr %#x.\n", hr);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+ ok(hr == DXGI_ERROR_UNSUPPORTED /* Win7 */
+ || hr == S_OK /* Win8~Win10 1909 */
+ || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE, /* Win10 2004 */
+ "Got unexpected hr %#x.\n", hr);
+
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ refcount = IDXGISwapChain_Release(swapchain);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ ret = restore_display_modes(original_modes, display_count);
+ ok(ret, "Failed to restore display modes.\n");
+
+ /* Test that mode restorations use display settings in the registry with a fullscreen device */
+ hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain);
+ ok(hr == S_OK, "CreateSwapChain failed, hr %#x.\n", hr);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+ if (FAILED(hr))
+ {
+ skip("SetFullscreenState failed, hr %#x.\n", hr);
+ refcount = IDXGISwapChain_Release(swapchain);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ goto done;
+ }
+
+ change_ret = ChangeDisplaySettingsW(&devmode, CDS_UPDATEREGISTRY | CDS_NORESET);
+ ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsW failed with %d.\n", change_ret);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ todo_wine ok(equal_mode_rect(&devmode2, &devmode), "Got a different mode.\n");
+ ret = EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ ok(equal_mode_rect(&devmode2, &devmode), "Got a different mode.\n");
+ refcount = IDXGISwapChain_Release(swapchain);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ ret = restore_display_modes(original_modes, display_count);
+ ok(ret, "Failed to restore display modes.\n");
+
+ for (adapter_idx = 0; SUCCEEDED(IDXGIFactory_EnumAdapters(factory, adapter_idx, &adapter)); ++adapter_idx)
+ {
+ for (output_idx = 0; SUCCEEDED(IDXGIAdapter_EnumOutputs(adapter, output_idx, &output)); ++output_idx)
+ {
+ hr = IDXGIOutput_GetDesc(output, &output_desc);
+ ok(hr == S_OK, "Adapter %u output %u: Got unexpected hr %#x.\n", adapter_idx, output_idx, hr);
+
+ if ((adapter_idx || output_idx) && output_desc.AttachedToDesktop)
+ {
+ second_output = output;
+ break;
+ }
+
+ IDXGIOutput_Release(output);
+ }
+
+ IDXGIAdapter_Release(adapter);
+ if (second_output)
+ break;
+ }
+
+ if (!second_output)
+ {
+ skip("Following tests require two monitors.\n");
+ goto done;
+ }
+ lstrcpyW(second_monitor_name, output_desc.DeviceName);
+
+ memset(&old_devmode, 0, sizeof(old_devmode));
+ old_devmode.dmSize = sizeof(old_devmode);
+ ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &old_devmode);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+
+ mode_idx = 0;
+ d3d_width = 0;
+ d3d_height = 0;
+ user32_width = 0;
+ user32_height = 0;
+ while (EnumDisplaySettingsW(second_monitor_name, mode_idx++, &devmode))
+ {
+ if (devmode.dmPelsWidth == old_devmode.dmPelsWidth
+ && devmode.dmPelsHeight == old_devmode.dmPelsHeight)
+ continue;
+
+ if (!d3d_width && !d3d_height)
+ {
+ d3d_width = devmode.dmPelsWidth;
+ d3d_height = devmode.dmPelsHeight;
+ continue;
+ }
+
+ if (devmode.dmPelsWidth == d3d_width && devmode.dmPelsHeight == d3d_height)
+ continue;
+
+ user32_width = devmode.dmPelsWidth;
+ user32_height = devmode.dmPelsHeight;
+ break;
+ }
+ if (!user32_width || !user32_height)
+ {
+ skip("Failed to find three different display modes for the second output.\n");
+ goto done;
+ }
+
+ /* Test that mode restorations for non-primary outputs upon fullscreen state changes */
+ hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain);
+ ok(hr == S_OK, "CreateSwapChain failed, hr %#x.\n", hr);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ change_ret = ChangeDisplaySettingsExW(second_monitor_name, &devmode, NULL, CDS_RESET, NULL);
+ ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExW failed with %d.\n", change_ret);
+ ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ if (devmode2.dmPelsWidth == old_devmode.dmPelsWidth
+ && devmode2.dmPelsHeight == old_devmode.dmPelsHeight)
+ {
+ skip("Failed to change display settings of the second monitor.\n");
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ refcount = IDXGISwapChain_Release(swapchain);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ goto done;
+ }
+
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ todo_wine ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
+ ret = EnumDisplaySettingsW(second_monitor_name, ENUM_REGISTRY_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
+ hr = IDXGIOutput_GetDesc(second_output, &output_desc);
+ ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
+ todo_wine ok(output_desc.DesktopCoordinates.right - output_desc.DesktopCoordinates.left ==
+ old_devmode.dmPelsWidth, "Expected width %u, got %u.\n", old_devmode.dmPelsWidth,
+ output_desc.DesktopCoordinates.right - output_desc.DesktopCoordinates.left);
+ todo_wine ok(output_desc.DesktopCoordinates.bottom - output_desc.DesktopCoordinates.top ==
+ old_devmode.dmPelsHeight, "Expected height %u, got %u.\n", old_devmode.dmPelsHeight,
+ output_desc.DesktopCoordinates.bottom - output_desc.DesktopCoordinates.top);
+
+ refcount = IDXGISwapChain_Release(swapchain);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ ret = restore_display_modes(original_modes, display_count);
+ ok(ret, "Failed to restore display modes.\n");
+
+ /* Test that mode restorations for non-primary outputs use display settings in the registry */
+ hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain);
+ ok(hr == S_OK, "CreateSwapChain failed, hr %#x.\n", hr);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+ ok(hr == S_OK, "SetFullscreenState failed, hr %#x.\n", hr);
+
+ change_ret = ChangeDisplaySettingsExW(second_monitor_name, &devmode, NULL,
+ CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
+ ok(change_ret == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExW failed with %d.\n", change_ret);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ ok(hr == S_OK, "SetFullscreenState failed, hr %#x.\n", hr);
+
+ ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ todo_wine ok(devmode2.dmPelsWidth == devmode.dmPelsWidth && devmode2.dmPelsHeight == devmode.dmPelsHeight,
+ "Expected resolution %ux%u, got %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight,
+ devmode2.dmPelsWidth, devmode2.dmPelsHeight);
+ ret = EnumDisplaySettingsW(second_monitor_name, ENUM_REGISTRY_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ ok(devmode2.dmPelsWidth == devmode.dmPelsWidth && devmode2.dmPelsHeight == devmode.dmPelsHeight,
+ "Expected resolution %ux%u, got %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight,
+ devmode2.dmPelsWidth, devmode2.dmPelsHeight);
+ hr = IDXGIOutput_GetDesc(second_output, &output_desc);
+ ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
+ todo_wine ok(output_desc.DesktopCoordinates.right - output_desc.DesktopCoordinates.left ==
+ devmode.dmPelsWidth, "Expected width %u, got %u.\n", devmode.dmPelsWidth,
+ output_desc.DesktopCoordinates.right - output_desc.DesktopCoordinates.left);
+ todo_wine ok(output_desc.DesktopCoordinates.bottom - output_desc.DesktopCoordinates.top ==
+ devmode.dmPelsHeight, "Expected height %u, got %u.\n", devmode.dmPelsHeight,
+ output_desc.DesktopCoordinates.bottom - output_desc.DesktopCoordinates.top);
+
+ refcount = IDXGISwapChain_Release(swapchain);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ ret = restore_display_modes(original_modes, display_count);
+ ok(ret, "Failed to restore display modes.\n");
+
+ /* Test that mode restorations for non-primary outputs on fullscreen state changes when there
+ * are two fullscreen swapchains on different outputs */
+ hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain);
+ ok(hr == S_OK, "CreateSwapChain failed, hr %#x.\n", hr);
+
+ swapchain_desc2 = swapchain_desc;
+ swapchain_desc.BufferDesc.Width = d3d_width;
+ swapchain_desc.BufferDesc.Height = d3d_height;
+ swapchain_desc2.OutputWindow = CreateWindowA("static", "dxgi_test2", 0,
+ old_devmode.dmPosition.x, old_devmode.dmPosition.y, 400, 200, 0, 0, 0, 0);
+ hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc2, &swapchain2);
+ ok(hr == S_OK, "CreateSwapChain failed, hr %#x.\n", hr);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+ ok(hr == S_OK, "SetFullscreenState failed, hr %#x.\n", hr);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain2, TRUE, NULL);
+ if (FAILED(hr))
+ {
+ skip("SetFullscreenState failed, hr %#x.\n", hr);
+ refcount = IDXGISwapChain_Release(swapchain2);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ ok(hr == S_OK, "SetFullscreenState failed, hr %#x.\n", hr);
+ refcount = IDXGISwapChain_Release(swapchain);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ goto done;
+ }
+
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ ok(hr == S_OK, "SetFullscreenState failed, hr %#x.\n", hr);
+ hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+ ok(hr == S_OK, "GetFullscreenState failed, hr %#x.\n", hr);
+ ok(!fullscreen, "Expected swapchain not fullscreen.\n");
+ hr = IDXGISwapChain_GetFullscreenState(swapchain2, &fullscreen, NULL);
+ ok(hr == S_OK, "GetFullscreenState failed, hr %#x.\n", hr);
+ ok(fullscreen, "Expected swapchain fullscreen.\n");
+
+ ret = EnumDisplaySettingsW(second_monitor_name, ENUM_CURRENT_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
+ ret = EnumDisplaySettingsW(second_monitor_name, ENUM_REGISTRY_SETTINGS, &devmode2);
+ ok(ret, "EnumDisplaySettingsW failed, error %#x.\n", GetLastError());
+ ok(equal_mode_rect(&devmode2, &old_devmode), "Got a different mode.\n");
+ hr = IDXGIOutput_GetDesc(second_output, &output_desc);
+ ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
+ ok(output_desc.DesktopCoordinates.right - output_desc.DesktopCoordinates.left ==
+ old_devmode.dmPelsWidth, "Expected width %u, got %u.\n", old_devmode.dmPelsWidth,
+ output_desc.DesktopCoordinates.right - output_desc.DesktopCoordinates.left);
+ ok(output_desc.DesktopCoordinates.bottom - output_desc.DesktopCoordinates.top ==
+ old_devmode.dmPelsHeight, "Expected height %u, got %u.\n", old_devmode.dmPelsHeight,
+ output_desc.DesktopCoordinates.bottom - output_desc.DesktopCoordinates.top);
+
+ hr = IDXGISwapChain_SetFullscreenState(swapchain2, FALSE, NULL);
+ ok(hr == S_OK, "SetFullscreenState failed, hr %#x.\n", hr);
+ refcount = IDXGISwapChain_Release(swapchain2);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ refcount = IDXGISwapChain_Release(swapchain);
+ ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
+ DestroyWindow(swapchain_desc2.OutputWindow);
+ ret = restore_display_modes(original_modes, display_count);
+ ok(ret, "Failed to restore display modes.\n");
+
+done:
+ if (second_output)
+ IDXGIOutput_Release(second_output);
+ DestroyWindow(swapchain_desc.OutputWindow);
+ refcount = IDXGIFactory_Release(factory);
+ ok(refcount == !is_d3d12, "Got unexpected refcount %u.\n", refcount);
+ ret = restore_display_modes(original_modes, display_count);
+ ok(ret, "Failed to restore display modes.\n");
+ heap_free(original_modes);
+}
+
static void run_on_d3d10(void (*test_func)(IUnknown *device, BOOL is_d3d12))
{
IDXGIDevice *device;
@@ -7013,6 +7438,7 @@ START_TEST(dxgi)
run_on_d3d10(test_get_containing_output);
run_on_d3d10(test_window_association);
run_on_d3d10(test_default_fullscreen_target_output);
+ run_on_d3d10(test_mode_change);
if (!(d3d12_module = LoadLibraryA("d3d12.dll")))
{
@@ -7042,6 +7468,7 @@ START_TEST(dxgi)
run_on_d3d12(test_get_containing_output);
run_on_d3d12(test_window_association);
run_on_d3d12(test_default_fullscreen_target_output);
+ run_on_d3d12(test_mode_change);
FreeLibrary(d3d12_module);
}
--
2.27.0
More information about the wine-devel
mailing list