FFXIV depends on this. It calls SetFullscreenState when it receives WM_WINDOWPOSCHANGED. Through luck the recursion aborts after two calls. The user-visible bug is that after leaving fullscreen, the game's window is still TOPMOST because we overwrite the stored pre-fullscreen window flags.
-- v2: dxgi/tests: Test nested SetFullscreenState from the same thread. dxgi/tests: Test nested fullscreen application from different thread. dxgi: Catch nested SetFullscreenState invocations. dxgi/tests: Run test_swapchain_window_messages on d3d12. dxgi/tests: Run test_resize_target_wndproc on d3d12 too. dxgi/tests: Fix UnregisterClass call in test_resize_target_wndproc.
From: Stefan Dösinger stefan@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 73ea891119f..665a59920a8 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -3418,7 +3418,7 @@ static DWORD WINAPI window_thread(void *data) DestroyWindow(thread_data->window); thread_data->window = NULL;
- UnregisterClassA("dxgi_test_wndproc_wc", GetModuleHandleA(NULL)); + UnregisterClassA("dxgi_resize_target_wndproc_wc", GetModuleHandleA(NULL));
return 0; }
From: Stefan Dösinger stefan@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 665a59920a8..4866be9ec1c 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -3423,15 +3423,13 @@ static DWORD WINAPI window_thread(void *data) return 0; }
-static void test_resize_target_wndproc(void) +static void test_resize_target_wndproc(IUnknown *device, BOOL is_d3d12) { struct window_thread_data thread_data; DXGI_SWAP_CHAIN_DESC swapchain_desc; IDXGISwapChain *swapchain; IDXGIFactory *factory; - IDXGIAdapter *adapter; DXGI_MODE_DESC mode; - IDXGIDevice *device; unsigned int ret; ULONG refcount; LONG_PTR data; @@ -3439,11 +3437,7 @@ static void test_resize_target_wndproc(void) HRESULT hr; RECT rect;
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } + get_factory(device, is_d3d12, &factory);
memset(&thread_data, 0, sizeof(thread_data)); thread_data.window_created = CreateEventA(NULL, FALSE, FALSE, NULL); @@ -3456,11 +3450,6 @@ static void test_resize_target_wndproc(void) ret = WaitForSingleObject(thread_data.window_created, INFINITE); ok(ret == WAIT_OBJECT_0, "Failed to wait for thread, ret %#x, last error %#lx.\n", ret, GetLastError());
- hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - swapchain_desc.BufferDesc.Width = 800; swapchain_desc.BufferDesc.Height = 600; swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; @@ -3471,12 +3460,12 @@ static void test_resize_target_wndproc(void) swapchain_desc.SampleDesc.Count = 1; swapchain_desc.SampleDesc.Quality = 0; swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapchain_desc.BufferCount = 1; + swapchain_desc.BufferCount = is_d3d12 ? 2 : 1; swapchain_desc.OutputWindow = thread_data.window; swapchain_desc.Windowed = TRUE; - swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD;; swapchain_desc.Flags = 0; - hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain); + hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
data = SetWindowLongPtrA(thread_data.window, GWLP_USERDATA, (LONG_PTR)swapchain); @@ -3503,11 +3492,8 @@ static void test_resize_target_wndproc(void) refcount = IDXGISwapChain_Release(swapchain); ok(!refcount, "IDXGISwapChain has %lu references left.\n", refcount);
- IDXGIAdapter_Release(adapter); - refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %lu references left.\n", refcount); refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %lu references left.\n", refcount); + ok(refcount == !is_d3d12, "Got unexpected refcount %lu.\n", refcount);
ret = SetEvent(thread_data.finished); ok(ret, "Failed to set event, last error %#lx.\n", GetLastError()); @@ -7664,7 +7650,6 @@ START_TEST(dxgi) queue_test(test_parents); queue_test(test_output); queue_test(test_find_closest_matching_mode); - queue_test(test_resize_target_wndproc); queue_test(test_create_factory); queue_test(test_private_data); queue_test(test_maximum_frame_latency); @@ -7696,6 +7681,7 @@ START_TEST(dxgi) run_on_d3d10(test_default_fullscreen_target_output); run_on_d3d10(test_mode_change); run_on_d3d10(test_swapchain_present_count); + run_on_d3d10(test_resize_target_wndproc);
if (!(d3d12_module = LoadLibraryA("d3d12.dll"))) { @@ -7727,6 +7713,7 @@ START_TEST(dxgi) run_on_d3d12(test_default_fullscreen_target_output); run_on_d3d12(test_mode_change); run_on_d3d12(test_swapchain_present_count); + run_on_d3d12(test_resize_target_wndproc);
FreeLibrary(d3d12_module); }
From: Stefan Dösinger stefan@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 4866be9ec1c..d21d8f886c2 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -5822,14 +5822,12 @@ static LRESULT CALLBACK test_wndproc(HWND hwnd, unsigned int message, WPARAM wpa return DefWindowProcA(hwnd, message, wparam, lparam); }
-static void test_swapchain_window_messages(void) +static void test_swapchain_window_messages(IUnknown *device, BOOL is_d3d12) { DXGI_SWAP_CHAIN_DESC swapchain_desc; IDXGISwapChain *swapchain; DXGI_MODE_DESC mode_desc; IDXGIFactory *factory; - IDXGIAdapter *adapter; - IDXGIDevice *device; ULONG refcount; WNDCLASSA wc; HWND window; @@ -5891,12 +5889,6 @@ static void test_swapchain_window_messages(void) {0, FALSE, 0}, };
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } - memset(&wc, 0, sizeof(wc)); wc.lpfnWndProc = test_wndproc; wc.lpszClassName = "dxgi_test_wndproc_wc"; @@ -5904,11 +5896,7 @@ static void test_swapchain_window_messages(void) window = CreateWindowA("dxgi_test_wndproc_wc", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); ok(!!window, "Failed to create window.\n");
- hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - IDXGIAdapter_Release(adapter); + get_factory(device, is_d3d12, &factory);
swapchain_desc.BufferDesc.Width = 800; swapchain_desc.BufferDesc.Height = 600; @@ -5920,16 +5908,16 @@ static void test_swapchain_window_messages(void) swapchain_desc.SampleDesc.Count = 1; swapchain_desc.SampleDesc.Quality = 0; swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapchain_desc.BufferCount = 1; + swapchain_desc.BufferCount = is_d3d12 ? 2 : 1; swapchain_desc.OutputWindow = window; swapchain_desc.Windowed = TRUE; - swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; swapchain_desc.Flags = 0;
/* create swapchain */ flush_events(); expect_no_messages = TRUE; - hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain); + hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); flush_events(); expect_no_messages = FALSE; @@ -5994,7 +5982,7 @@ static void test_swapchain_window_messages(void)
expect_messages = enter_fullscreen_messages; expect_messages_broken = enter_fullscreen_messages_vista; - hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain); + hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); flush_events(); todo_wine @@ -6016,10 +6004,8 @@ done: ok(!refcount, "IDXGISwapChain has %lu references left.\n", refcount); DestroyWindow(window);
- refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %lu references left.\n", refcount); refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %lu references left.\n", refcount); + ok(refcount == !is_d3d12, "Got unexpected refcount %lu.\n", refcount);
UnregisterClassA("dxgi_test_wndproc_wc", GetModuleHandleA(NULL)); } @@ -7666,7 +7652,6 @@ START_TEST(dxgi) test_gamma_control(); test_multi_adapter(); test_swapchain_parameters(); - test_swapchain_window_messages(); test_swapchain_window_styles(); run_on_d3d10(test_set_fullscreen); run_on_d3d10(test_resize_target); @@ -7682,6 +7667,7 @@ START_TEST(dxgi) run_on_d3d10(test_mode_change); run_on_d3d10(test_swapchain_present_count); run_on_d3d10(test_resize_target_wndproc); + run_on_d3d10(test_swapchain_window_messages);
if (!(d3d12_module = LoadLibraryA("d3d12.dll"))) { @@ -7714,6 +7700,7 @@ START_TEST(dxgi) run_on_d3d12(test_mode_change); run_on_d3d12(test_swapchain_present_count); run_on_d3d12(test_resize_target_wndproc); + run_on_d3d12(test_swapchain_window_messages);
FreeLibrary(d3d12_module); }
From: Stefan Dösinger stefan@codeweavers.com
--- dlls/dxgi/dxgi_private.h | 1 + dlls/dxgi/swapchain.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+)
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index dd17e39eca6..0e47859a445 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -183,6 +183,7 @@ struct d3d11_swapchain
IDXGIOutput *target; LONG present_count; + LONG nested_sfs; };
HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_device *device, diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 9677142e0af..e3d335c5474 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -383,6 +383,8 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen struct wined3d_swapchain_desc swapchain_desc; struct wined3d_swapchain_state *state; struct dxgi_output *dxgi_output; + LONG nested_sfs; + BOOL old_fs; HRESULT hr;
TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target); @@ -404,6 +406,19 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen } dxgi_output = unsafe_impl_from_IDXGIOutput(target);
+ /* DXGI catches nested SetFullscreenState invocations, earlier versions of d3d + * do not. Final Fantasy XIV depends on this behavior. It tries to call SFS on + * WM_WINDOWPOSCHANGED messages. */ + nested_sfs = InterlockedExchange(&swapchain->nested_sfs, 1); + + if (nested_sfs) + { + WARN("Nested invocation of SetFullscreenState.\n"); + IDXGIOutput_Release(target); + IDXGISwapChain1_GetFullscreenState(iface, &old_fs, NULL); + return old_fs == fullscreen ? S_OK : DXGI_STATUS_MODE_CHANGE_IN_PROGRESS; + } + wined3d_mutex_lock(); state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain); wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &swapchain_desc); @@ -411,6 +426,9 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen swapchain_desc.windowed = !fullscreen; hr = wined3d_swapchain_state_set_fullscreen(state, &swapchain_desc, NULL); wined3d_mutex_unlock(); + + nested_sfs = InterlockedExchange(&swapchain->nested_sfs, 0); + if (FAILED(hr)) { IDXGIOutput_Release(target); @@ -1015,6 +1033,7 @@ struct d3d12_swapchain IDXGIOutput *target; DXGI_SWAP_CHAIN_DESC1 desc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc; + LONG nested_sfs;
ID3D12Fence *frame_latency_fence; HANDLE frame_latency_event; @@ -2173,6 +2192,8 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc = &swapchain->desc; struct wined3d_swapchain_desc wined3d_desc; HWND window = swapchain->window; + LONG nested_sfs; + BOOL old_fs; HRESULT hr;
TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target); @@ -2196,10 +2217,24 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, target, window, swapchain_desc, fullscreen_desc))) goto fail; + + nested_sfs = InterlockedExchange(&swapchain->nested_sfs, 1); + + if (nested_sfs) + { + WARN("Nested invocation of SetFullscreenState.\n"); + IDXGIOutput_Release(target); + IDXGISwapChain4_GetFullscreenState(iface, &old_fs, NULL); + return old_fs == fullscreen ? S_OK : DXGI_STATUS_MODE_CHANGE_IN_PROGRESS; + } + wined3d_mutex_lock(); wined3d_desc.windowed = !fullscreen; hr = wined3d_swapchain_state_set_fullscreen(swapchain->state, &wined3d_desc, NULL); wined3d_mutex_unlock(); + + InterlockedExchange(&swapchain->nested_sfs, 0); + if (FAILED(hr)) goto fail;
From: Stefan Dösinger stefan@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 47 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index d21d8f886c2..560ae7bf321 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -3358,25 +3358,42 @@ static void test_resize_target(IUnknown *device, BOOL is_d3d12) ok(refcount == !is_d3d12, "Got unexpected refcount %lu.\n", refcount); }
+struct resize_target_data +{ + IDXGISwapChain *swapchain; + BOOL test_nested_sfs; +}; + static LRESULT CALLBACK resize_target_wndproc(HWND hwnd, unsigned int message, WPARAM wparam, LPARAM lparam) { - IDXGISwapChain *swapchain = (IDXGISwapChain *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + struct resize_target_data *data = (struct resize_target_data *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); DXGI_SWAP_CHAIN_DESC desc; HRESULT hr; + BOOL fs;
switch (message) { case WM_SIZE: - ok(!!swapchain, "GWLP_USERDATA is NULL.\n"); - hr = IDXGISwapChain_GetDesc(swapchain, &desc); + ok(!!data, "GWLP_USERDATA is NULL.\n"); + hr = IDXGISwapChain_GetDesc(data->swapchain, &desc); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(desc.BufferDesc.Width == 800, "Got unexpected buffer width %u.\n", desc.BufferDesc.Width); ok(desc.BufferDesc.Height == 600, "Got unexpected buffer height %u.\n", desc.BufferDesc.Height); return 0;
- default: - return DefWindowProcA(hwnd, message, wparam, lparam); + case WM_WINDOWPOSCHANGED: + if (!data->test_nested_sfs) + break; + + /* We are not supposed to deadlock if the window is owned by a different thread. + * The current fullscreen state and consequently the return value of the nested + * SetFullscreenState call are racy on Windows, do not test them. */ + hr = IDXGISwapChain_GetFullscreenState(data->swapchain, &fs, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + IDXGISwapChain_SetFullscreenState(data->swapchain, FALSE, NULL); + break; } + return DefWindowProcA(hwnd, message, wparam, lparam); }
struct window_thread_data @@ -3425,6 +3442,7 @@ static DWORD WINAPI window_thread(void *data)
static void test_resize_target_wndproc(IUnknown *device, BOOL is_d3d12) { + struct resize_target_data window_data = {0}; struct window_thread_data thread_data; DXGI_SWAP_CHAIN_DESC swapchain_desc; IDXGISwapChain *swapchain; @@ -3436,6 +3454,7 @@ static void test_resize_target_wndproc(IUnknown *device, BOOL is_d3d12) HANDLE thread; HRESULT hr; RECT rect; + BOOL fs;
get_factory(device, is_d3d12, &factory);
@@ -3468,7 +3487,8 @@ static void test_resize_target_wndproc(IUnknown *device, BOOL is_d3d12) hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- data = SetWindowLongPtrA(thread_data.window, GWLP_USERDATA, (LONG_PTR)swapchain); + window_data.swapchain = swapchain; + data = SetWindowLongPtrA(thread_data.window, GWLP_USERDATA, (LONG_PTR)&window_data); ok(!data, "Got unexpected GWLP_USERDATA %p.\n", (void *)data);
memset(&mode, 0, sizeof(mode)); @@ -3489,6 +3509,21 @@ static void test_resize_target_wndproc(IUnknown *device, BOOL is_d3d12) ok(rect.right == mode.Width && rect.bottom == mode.Height, "Got unexpected client rect %s.\n", wine_dbgstr_rect(&rect));
+ /* Win7 testbot reports no output for the swapchain and can't switch to fullscreen. */ + window_data.test_nested_sfs = TRUE; + hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL); + ok(hr == S_OK || broken(hr == DXGI_ERROR_UNSUPPORTED), "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fs, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(fs, "Got unexpected fullscreen state %x.\n", fs); + } + window_data.test_nested_sfs = FALSE; + + hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + refcount = IDXGISwapChain_Release(swapchain); ok(!refcount, "IDXGISwapChain has %lu references left.\n", refcount);
From: Stefan Dösinger stefan@codeweavers.com
I am still deliberately not testing after which message the swapchain state changes from the old state to the new until we find a game that depends on this.
ddraw, d3d8 and d3d9 do not catch recursive SetDisplayMode or Reset() calls. They will recurse for about 16 times and then return library specific weird return values like 0xd0000510 (NTSTATUS, but nonexistent facility) or 0x88760868 (non-existent HRESULT facility). I suspect it aborts when the kernel-side message processing stack is exhausted. As such, an application depending on nested calls in those libraries would have to deliberately do it, but limit the amount of nesting to a non-zero amount. --- dlls/dxgi/tests/dxgi.c | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 560ae7bf321..c0d63dc3713 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -5838,14 +5838,54 @@ static BOOL check_message(const struct message *expected,
static LRESULT CALLBACK test_wndproc(HWND hwnd, unsigned int message, WPARAM wparam, LPARAM lparam) { + IDXGISwapChain *swapchain = (IDXGISwapChain *)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + static BOOL reentry; + IDXGIOutput *target; + HRESULT hr, hr2; + BOOL fs; + flaky ok(!expect_no_messages, "Got unexpected message %#x, hwnd %p, wparam %#Ix, lparam %#Ix.\n", message, hwnd, wparam, lparam);
+ ok(!reentry, "Re-entered wndproc in nested SetFullscreenState call\n"); + if (expect_messages) { if (check_message(expect_messages, hwnd, message, wparam, lparam)) + { ++expect_messages; + + if (swapchain) + { + reentry = TRUE; + + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fs, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Priority of error values. */ + hr = IDXGISwapChain_GetContainingOutput(swapchain, &target); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, target); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", DXGI_ERROR_INVALID_CALL); + IDXGIOutput_Release(target); + + hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL); + hr2 = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); + + if (fs) + { + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(hr2 == DXGI_STATUS_MODE_CHANGE_IN_PROGRESS, "Got unexpected hr %#lx.\n", hr); + } + else + { + ok(hr == DXGI_STATUS_MODE_CHANGE_IN_PROGRESS, "Got unexpected hr %#lx.\n", hr); + ok(hr2 == S_OK, "Got unexpected hr %#lx.\n", hr); + } + reentry = FALSE; + } + } }
if (expect_messages_broken) @@ -5977,12 +6017,14 @@ static void test_swapchain_window_messages(IUnknown *device, BOOL is_d3d12) ok(!expect_messages->message, "Expected message %#x.\n", expect_messages->message);
/* enter fullscreen */ + SetWindowLongPtrA(window, GWLP_USERDATA, (LONG_PTR)swapchain); expect_messages = enter_fullscreen_messages; expect_messages_broken = enter_fullscreen_messages_vista; hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL); ok(hr == S_OK || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE || broken(hr == DXGI_ERROR_UNSUPPORTED), /* Win 7 testbot */ "Got unexpected hr %#lx.\n", hr); + SetWindowLongPtrA(window, GWLP_USERDATA, (LONG_PTR)NULL); if (FAILED(hr)) { skip("Could not change fullscreen state.\n"); @@ -6027,9 +6069,11 @@ static void test_swapchain_window_messages(IUnknown *device, BOOL is_d3d12) expect_messages_broken = NULL;
/* leave fullscreen */ + SetWindowLongPtrA(window, GWLP_USERDATA, (LONG_PTR)swapchain); expect_messages = leave_fullscreen_messages; hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + SetWindowLongPtrA(window, GWLP_USERDATA, (LONG_PTR)NULL); flush_events(); ok(!expect_messages->message, "Expected message %#x.\n", expect_messages->message); expect_messages = NULL;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=128446
Your paranoid android.
=== w864 (32 bit report) ===
dxgi: dxgi: Timeout
This merge request was approved by Jan Sikorski.
Hold back on this for now, I'll see if I can make the synchronization of this function nicer.
Zebediah Figura (@zfigura) commented about dlls/dxgi/dxgi_private.h:
IDXGIOutput *target; LONG present_count;
- LONG nested_sfs;
FWIW, I'm not a fan of this naming; the abbreviation is not very obvious, and "nested" is misleading since this is true even when there's only one call. I'd advocate for something more like "in_set_fullscreen_state".