Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/dxgi/tests/dxgi.c | 201 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 201 insertions(+)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index f8d987eacc..3d6e7f99b2 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -476,6 +476,25 @@ 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_(INT line, IDXGISwapChain *swapchain, BOOL expected, BOOL todo)
+{
+ static const DWORD wait_timeout = 2000;
+ static const DWORD wait_step = 100;
+ DWORD total_time = 0;
+ BOOL got;
+ do
+ {
+ got = !expected;
+ IDXGISwapChain_GetFullscreenState(swapchain, &got, NULL);
+ if (got == expected)
+ break;
+ Sleep(wait_step);
+ total_time += wait_step;
+ } while (total_time < wait_timeout);
+ todo_wine_if(todo) ok_(__FILE__, line)(got == expected, "Expect %#x, got %#x.\n", expected, got);
+}
+
static IDXGIAdapter *create_adapter(void)
{
IDXGIFactory4 *factory4;
@@ -4002,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;
@@ -4039,6 +4061,185 @@ 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_hwnd = CreateWindowA("static", "occluding_window", WS_POPUP | WS_VISIBLE, 0, 0, 400, 200, 0, 0, 0, 0);
+
+ /* Another window covers the swapchain window, doesn't report as occluded */
+ hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ /* Minimized 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), "Got unexpected hr %#x.\n", 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, "Got unexpected hr %#x.\n", hr);
+ ShowWindow(swapchain_desc.OutputWindow, SW_SHOW);
+ DestroyWindow(occluding_hwnd);
+
+ /* Test 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 Win 7 testbot. */
+ if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE || broken(hr == DXGI_ERROR_UNSUPPORTED))
+ {
+ skip("Could not change fullscreen state.\n");
+ continue;
+ }
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ output = NULL;
+ fullscreen = FALSE;
+ hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, &output);
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ todo_wine_if(is_d3d12) ok(fullscreen, "Unexpected fullscreen status.\n");
+ todo_wine_if(is_d3d12) ok(output != NULL, "Expect output not null.\n");
+
+ if (output) IDXGIOutput_ReleaseOwnership(output);
+ /* Still in fullscreen */
+ fullscreen = FALSE;
+ hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ todo_wine_if(is_d3d12) ok(fullscreen, "Unexpected fullscreen status.\n");
+ /* Now calling IDXGISwapChain_Present will exit the fullscreen */
+ hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ fullscreen = TRUE;
+ hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ /* Now fullscreen mode is exited */
+ if (flags[i] == 0 && !is_d3d12)
+ {
+ /* Still on fullscreen on vista and 2008 */
+ todo_wine ok(!fullscreen || broken(fullscreen), "Unexpected fullscreen status.\n");
+ }
+ else
+ {
+ ok(fullscreen, "Unexpected fullscreen status.\n");
+ }
+ 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, new occluding window doesn't break swapchain out of fullscreen because d3d12 swapchain
+ * fullscreen mode doesn't take exclusive ownership over output, nor does it 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, "Got unexpected hr %#x.\n", hr);
+ fullscreen = FALSE;
+ hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ todo_wine_if(is_d3d12) ok(fullscreen, "Unexpected fullscreen status.\n");
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ occluding_hwnd = CreateWindowA("static", "occluding_window", WS_POPUP, 0, 0, 400, 200, 0, 0, 0, 0);
+ /* Invisible window doesn't cause fullscreen mode to exit */
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ fullscreen = FALSE;
+ hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ todo_wine_if(is_d3d12) ok(fullscreen, "Unexpected fullscreen status.\n");
+ /* Visible but with bottom z-order window still cause fullscreen mode to exit for d3d11 */
+ SetWindowPos(occluding_hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ ShowWindow(occluding_hwnd, 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, "Got unexpected hr %#x.\n", hr);
+ todo_wine_if(!is_d3d12) ok(is_d3d12 ? fullscreen : !fullscreen, "Unexpected fullscreen status.\n");
+
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+ todo_wine_if(is_d3d12) ok(hr == (is_d3d12 ? DXGI_STATUS_OCCLUDED : S_OK), "Got unexpected hr %#x.\n", hr);
+
+ fullscreen = TRUE;
+ hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ if (flags[i] == DXGI_PRESENT_TEST)
+ {
+ todo_wine_if(!is_d3d12) ok(is_d3d12 ? fullscreen : !fullscreen, "Unexpected fullscreen status.\n");
+ }
+ else
+ {
+ todo_wine ok(!fullscreen, "Unexpected fullscreen status.\n");
+ }
+
+ /* 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 */
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ 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), "Got unexpected hr %#x.\n", hr);
+ }
+ else
+ {
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ }
+
+ /* Trying break out of fullscreen mode again. This time, don't call IDXGISwapChain_GetFullscreenState before
+ * IDXGISwapChain_Present */
+ ShowWindow(occluding_hwnd, SW_HIDE);
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ShowWindow(occluding_hwnd, SW_SHOW);
+
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ 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), "Got unexpected hr %#x.\n", hr);
+
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+ if (flags[i] == DXGI_PRESENT_TEST)
+ {
+ todo_wine ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == S_OK), "Got unexpected hr %#x.\n", hr);
+ /* IDXGISwapChain_Present without flags refresh the occlusion state */
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ hr = IDXGISwapChain_Present(swapchain, 0, 0);
+ todo_wine ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == S_OK), "Got unexpected hr %#x.\n", hr);
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ hr = IDXGISwapChain_Present(swapchain, 0, DXGI_PRESENT_TEST);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ }
+ else
+ {
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ }
+ fullscreen = TRUE;
+ hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ todo_wine ok(!fullscreen, "Unexpected fullscreen status.\n");
+
+ DestroyWindow(occluding_hwnd);
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ hr = IDXGISwapChain_Present(swapchain, 0, flags[i]);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
+ todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ IDXGISwapChain_ResizeBuffers(swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+ }
+
wait_device_idle(device);
IDXGISwapChain_Release(swapchain);
--
2.20.1