From: Zhiyi Zhang <zzhang(a)codeweavers.com>
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)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