[PATCH 5/7] dxgi/tests: Add more IDXGISwapChain_Present() tests.

Henri Verbeet hverbeet at codeweavers.com
Mon Jun 24 16:59:46 CDT 2019


From: Zhiyi Zhang <zzhang at codeweavers.com>

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
This supersedes patch 166451.

 dlls/dxgi/tests/dxgi.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 222 insertions(+)

diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index 69c868cf3b4..51ff4405b4e 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -468,6 +468,30 @@ static void compute_expected_swapchain_fullscreen_state_after_fullscreen_change_
     }
 }
 
+#define wait_fullscreen_state(a, b, c) wait_fullscreen_state_(__LINE__, a, b, c)
+static void wait_fullscreen_state_(unsigned int line, IDXGISwapChain *swapchain, BOOL expected, BOOL todo)
+{
+    static const unsigned int wait_timeout = 2000;
+    static const unsigned int wait_step = 100;
+    unsigned int total_time = 0;
+    HRESULT hr;
+    BOOL state;
+
+    while (total_time < wait_timeout)
+    {
+        state = !expected;
+        if (FAILED(hr = IDXGISwapChain_GetFullscreenState(swapchain, &state, NULL)))
+            break;
+        if (state == expected)
+            break;
+        Sleep(wait_step);
+        total_time += wait_step;
+    }
+    ok_(__FILE__, line)(hr == S_OK, "Failed to get fullscreen state, hr %#x.\n", hr);
+    todo_wine_if(todo) ok_(__FILE__, line)(state == expected,
+            "Got unexpected state %#x, expected %#x.\n", state, expected);
+}
+
 static IDXGIAdapter *create_adapter(void)
 {
     IDXGIFactory4 *factory4;
@@ -3997,9 +4021,12 @@ static void test_swapchain_parameters(void)
 
 static void test_swapchain_present(IUnknown *device, BOOL is_d3d12)
 {
+    static const DWORD flags[] = {0, DXGI_PRESENT_TEST};
     DXGI_SWAP_CHAIN_DESC swapchain_desc;
     IDXGISwapChain *swapchain;
     IDXGIFactory *factory;
+    IDXGIOutput *output;
+    BOOL fullscreen;
     unsigned int i;
     ULONG refcount;
     HRESULT hr;
@@ -4034,6 +4061,201 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12)
     hr = IDXGISwapChain_Present(swapchain, 0, 0);
     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
 
+    for (i = 0; i < ARRAY_SIZE(flags); ++i)
+    {
+        HWND occluding_window = CreateWindowA("static", "occluding_window",
+                WS_POPUP | WS_VISIBLE, 0, 0, 400, 200, NULL, NULL, NULL, NULL);
+
+        /* Another window covers the swapchain window. Not reported as occluded. */
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+
+        /* Minimised window. */
+        ShowWindow(swapchain_desc.OutputWindow, SW_MINIMIZE);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        todo_wine_if(!is_d3d12) ok(hr == (is_d3d12 ? S_OK : DXGI_STATUS_OCCLUDED),
+                "Test %u: Got unexpected hr %#x.\n", i, hr);
+        ShowWindow(swapchain_desc.OutputWindow, SW_NORMAL);
+
+        /* Hidden window. */
+        ShowWindow(swapchain_desc.OutputWindow, SW_HIDE);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        ShowWindow(swapchain_desc.OutputWindow, SW_SHOW);
+        DestroyWindow(occluding_window);
+
+        /* Test that IDXGIOutput_ReleaseOwnership() makes the swapchain exit
+         * fullscreen. */
+        hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+        /* DXGI_ERROR_NOT_CURRENTLY_AVAILABLE on some machines.
+         * DXGI_ERROR_UNSUPPORTED on the Windows 7 testbot. */
+        if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE || broken(hr == DXGI_ERROR_UNSUPPORTED))
+        {
+            skip("Test %u: Could not change fullscreen state.\n", i);
+            continue;
+        }
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+        todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        output = NULL;
+        fullscreen = FALSE;
+        hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, &output);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        todo_wine_if(is_d3d12) ok(fullscreen, "Test %u: Got unexpected fullscreen status.\n", i);
+        todo_wine_if(is_d3d12) ok(!!output, "Test %u: Got unexpected output.\n", i);
+
+        if (output)
+            IDXGIOutput_ReleaseOwnership(output);
+        /* Still fullscreen. */
+        fullscreen = FALSE;
+        hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        todo_wine_if(is_d3d12) ok(fullscreen, "Test %u: Got unexpected fullscreen status.\n", i);
+        /* Calling IDXGISwapChain_Present() will exit fullscreen. */
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        fullscreen = TRUE;
+        hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        /* Now fullscreen mode is exited. */
+        if (!flags[i] && !is_d3d12)
+            /* Still fullscreen on vista and 2008. */
+            todo_wine ok(!fullscreen || broken(fullscreen), "Test %u: Got unexpected fullscreen status.\n", i);
+        else
+            ok(fullscreen, "Test %u: Got unexpected fullscreen status.\n", i);
+        if (output)
+            IDXGIOutput_Release(output);
+
+        /* Test creating a window when swapchain is in fullscreen.
+         *
+         * The window should break the swapchain out of fullscreen mode on
+         * d3d10/11. D3d12 is different, a new occluding window doesn't break
+         * the swapchain out of fullscreen because d3d12 fullscreen swapchains
+         * don't take exclusive ownership over the output, nor do they disable
+         * compositing. D3d12 fullscreen mode acts just like borderless
+         * fullscreen window mode. */
+        hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        fullscreen = FALSE;
+        hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        todo_wine_if(is_d3d12) ok(fullscreen, "Test %u: Got unexpected fullscreen status.\n", i);
+        hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+        todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+
+        occluding_window = CreateWindowA("static", "occluding_window", WS_POPUP, 0, 0, 400, 200, 0, 0, 0, 0);
+        /* An invisible window doesn't cause the swapchain to exit fullscreen
+         * mode. */
+        hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+        todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        fullscreen = FALSE;
+        hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        todo_wine_if(is_d3d12) ok(fullscreen, "Test %u: Got unexpected fullscreen status.\n", i);
+        /* A visible, but with bottom z-order window still causes the
+         * swapchain to exit fullscreen mode. */
+        SetWindowPos(occluding_window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+        ShowWindow(occluding_window, SW_SHOW);
+        /* Fullscreen mode takes a while to exit. */
+        if (!is_d3d12)
+            wait_fullscreen_state(swapchain, FALSE, TRUE);
+
+        /* No longer fullscreen before calling IDXGISwapChain_Present() except
+         * for d3d12. */
+        fullscreen = TRUE;
+        hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        todo_wine_if(!is_d3d12) ok(is_d3d12 ? fullscreen : !fullscreen,
+                "Test %u: Got unexpected fullscreen status.\n", i);
+
+        hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+        todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        todo_wine_if(is_d3d12) ok(hr == (is_d3d12 ? DXGI_STATUS_OCCLUDED : S_OK),
+                "Test %u: Got unexpected hr %#x.\n", i, hr);
+
+        fullscreen = TRUE;
+        hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        if (flags[i] == DXGI_PRESENT_TEST)
+            todo_wine_if(!is_d3d12) ok(is_d3d12 ? fullscreen : !fullscreen,
+                    "Test %u: Got unexpected fullscreen status.\n", i);
+        else
+            todo_wine ok(!fullscreen, "Test %u: Got unexpected fullscreen status.\n", i);
+
+        /* Even though d3d12 doesn't exit fullscreen, a
+         * IDXGISwapChain_ResizeBuffers() is still needed for subsequent
+         * IDXGISwapChain_Present() calls to work, otherwise they will return
+         * DXGI_ERROR_INVALID_CALL */
+        hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+        todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        if (flags[i] == DXGI_PRESENT_TEST)
+            todo_wine_if(is_d3d12) ok(hr == (is_d3d12 ? DXGI_STATUS_OCCLUDED : S_OK),
+                    "Test %u: Got unexpected hr %#x.\n", i, hr);
+        else
+            ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+
+        /* Trying to break out of fullscreen mode again. This time, don't call
+         * IDXGISwapChain_GetFullscreenState() before IDXGISwapChain_Present(). */
+        ShowWindow(occluding_window, SW_HIDE);
+        hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        ShowWindow(occluding_window, SW_SHOW);
+
+        hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+        todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        /* hr == S_OK on vista and 2008 */
+        todo_wine ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == S_OK),
+                "Test %u: Got unexpected hr %#x.\n", i, hr);
+
+        hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+        todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        if (flags[i] == DXGI_PRESENT_TEST)
+        {
+            todo_wine ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == S_OK),
+                    "Test %u: Got unexpected hr %#x.\n", i, hr);
+            /* IDXGISwapChain_Present() without flags refreshes the occlusion
+             * state. */
+            hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+            todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+            hr = IDXGISwapChain_Present(swapchain, 0, 0);
+            todo_wine ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == S_OK),
+                    "Test %u: Got unexpected hr %#x.\n", i, hr);
+            hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+            todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+            hr = IDXGISwapChain_Present(swapchain, 0, DXGI_PRESENT_TEST);
+            ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        }
+        else
+        {
+            ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        }
+        fullscreen = TRUE;
+        hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        todo_wine ok(!fullscreen, "Test %u: Got unexpected fullscreen status.\n", i);
+
+        DestroyWindow(occluding_window);
+        hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+        todo_wine_if(!is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+        ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+
+        hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+        todo_wine_if(is_d3d12) ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+        hr = IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+        ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
+    }
+
     wait_device_idle(device);
 
     IDXGISwapChain_Release(swapchain);
-- 
2.11.0




More information about the wine-devel mailing list