Commit 33170e27 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

dxgi: Catch nested SetFullscreenState invocations.

parent 75f7bd0e
...@@ -183,6 +183,7 @@ struct d3d11_swapchain ...@@ -183,6 +183,7 @@ struct d3d11_swapchain
IDXGIOutput *target; IDXGIOutput *target;
LONG present_count; LONG present_count;
LONG in_set_fullscreen_state;
}; };
HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_device *device, HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_device *device,
......
...@@ -383,6 +383,8 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen ...@@ -383,6 +383,8 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen
struct wined3d_swapchain_desc swapchain_desc; struct wined3d_swapchain_desc swapchain_desc;
struct wined3d_swapchain_state *state; struct wined3d_swapchain_state *state;
struct dxgi_output *dxgi_output; struct dxgi_output *dxgi_output;
LONG in_set_fullscreen_state;
BOOL old_fs;
HRESULT hr; HRESULT hr;
TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target); TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target);
...@@ -404,6 +406,18 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen ...@@ -404,6 +406,18 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen
} }
dxgi_output = unsafe_impl_from_IDXGIOutput(target); 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. */
in_set_fullscreen_state = InterlockedExchange(&swapchain->in_set_fullscreen_state, 1);
if (in_set_fullscreen_state)
{
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(); wined3d_mutex_lock();
state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain); state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain);
wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &swapchain_desc); wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &swapchain_desc);
...@@ -429,6 +443,7 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen ...@@ -429,6 +443,7 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen
done: done:
wined3d_mutex_unlock(); wined3d_mutex_unlock();
InterlockedExchange(&swapchain->in_set_fullscreen_state, 0);
return hr; return hr;
} }
...@@ -1016,6 +1031,7 @@ struct d3d12_swapchain ...@@ -1016,6 +1031,7 @@ struct d3d12_swapchain
IDXGIOutput *target; IDXGIOutput *target;
DXGI_SWAP_CHAIN_DESC1 desc; DXGI_SWAP_CHAIN_DESC1 desc;
DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc;
LONG in_set_fullscreen_state;
ID3D12Fence *frame_latency_fence; ID3D12Fence *frame_latency_fence;
HANDLE frame_latency_event; HANDLE frame_latency_event;
...@@ -2077,6 +2093,8 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen ...@@ -2077,6 +2093,8 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen
const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc = &swapchain->desc; const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc = &swapchain->desc;
struct wined3d_swapchain_desc wined3d_desc; struct wined3d_swapchain_desc wined3d_desc;
HWND window = swapchain->window; HWND window = swapchain->window;
LONG in_set_fullscreen_state;
BOOL old_fs;
HRESULT hr; HRESULT hr;
TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target); TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target);
...@@ -2104,6 +2122,15 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen ...@@ -2104,6 +2122,15 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen
return hr; return hr;
} }
in_set_fullscreen_state = InterlockedExchange(&swapchain->in_set_fullscreen_state, 1);
if (in_set_fullscreen_state)
{
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_mutex_lock();
wined3d_desc.windowed = !fullscreen; wined3d_desc.windowed = !fullscreen;
hr = wined3d_swapchain_state_set_fullscreen(swapchain->state, &wined3d_desc, NULL); hr = wined3d_swapchain_state_set_fullscreen(swapchain->state, &wined3d_desc, NULL);
...@@ -2127,6 +2154,7 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen ...@@ -2127,6 +2154,7 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen
done: done:
wined3d_mutex_unlock(); wined3d_mutex_unlock();
InterlockedExchange(&swapchain->in_set_fullscreen_state, 0);
return hr; return hr;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment