Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/dxgi_private.h | 2 + dlls/dxgi/output.c | 69 ++++++++++++++++++++++++++++++++ dlls/dxgi/swapchain.c | 82 ++++++++++++++++++++++++++++++++------- dlls/wined3d/swapchain.c | 58 --------------------------- dlls/wined3d/wined3d.spec | 1 - include/wine/wined3d.h | 2 - 6 files changed, 138 insertions(+), 76 deletions(-)
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index 553eace..e3c264a 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -148,6 +148,8 @@ struct dxgi_output };
HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output) DECLSPEC_HIDDEN; +HRESULT dxgi_output_get_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *mode_desc) DECLSPEC_HIDDEN; +HRESULT dxgi_output_set_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *target_mode_desc) DECLSPEC_HIDDEN;
/* IDXGIAdapter */ struct dxgi_adapter diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index 123dee8..6d5a2ac 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -522,6 +522,14 @@ static const struct IDXGIOutput4Vtbl dxgi_output_vtbl = dxgi_output_CheckOverlayColorSpaceSupport, };
+struct dxgi_output *unsafe_impl_from_IDXGIOutput(IDXGIOutput *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == (IDXGIOutputVtbl *)&dxgi_output_vtbl); + return impl_from_IDXGIOutput4((IDXGIOutput4 *)iface); +} + static void dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter) { output->IDXGIOutput4_iface.lpVtbl = &dxgi_output_vtbl; @@ -539,3 +547,64 @@ HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **ou dxgi_output_init(*output, adapter); return S_OK; } + +HRESULT dxgi_output_get_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *mode) +{ + struct wined3d_display_mode wined3d_mode; + struct dxgi_adapter *adapter; + struct dxgi_output *target; + struct wined3d *wined3d; + HRESULT hr; + + target = unsafe_impl_from_IDXGIOutput(iface); + adapter = target->adapter; + wined3d = adapter->factory->wined3d; + + wined3d_mutex_lock(); + hr = wined3d_get_adapter_display_mode(wined3d, adapter->ordinal, &wined3d_mode, NULL); + wined3d_mutex_unlock(); + + if (FAILED(hr)) + { + WARN("Failed to get display mode, hr %#x.\n", hr); + return DXGI_ERROR_INVALID_CALL; + } + + dxgi_mode_from_wined3d(mode, &wined3d_mode); + + TRACE("Returning %s.\n", debug_dxgi_mode(mode)); + + return S_OK; +} + +HRESULT dxgi_output_set_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *mode) +{ + struct wined3d_display_mode wined3d_mode; + struct dxgi_adapter *adapter; + struct dxgi_output *target; + struct wined3d *wined3d; + HRESULT hr; + + target = unsafe_impl_from_IDXGIOutput(iface); + adapter = target->adapter; + wined3d = adapter->factory->wined3d; + + wined3d_display_mode_from_dxgi(&wined3d_mode, mode); + + if (FAILED(hr = dxgi_output_find_closest_matching_mode(target, &wined3d_mode, NULL))) + WARN("Failed to find closest matching mode, hr %#x.\n", hr); + else /* Copy the actual mode back to the caller */ + dxgi_mode_from_wined3d(mode, &wined3d_mode); + + wined3d_mutex_lock(); + hr = wined3d_set_adapter_display_mode(wined3d, adapter->ordinal, &wined3d_mode); + wined3d_mutex_unlock(); + + if (FAILED(hr)) + { + WARN("Failed to set display mode, hr %#x.\n", hr); + return DXGI_ERROR_INVALID_CALL; + } + + return S_OK; +} diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 8dbbfab..3bf4202 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -152,6 +152,70 @@ static HRESULT dxgi_get_output_from_window(IDXGIAdapter *adapter, HWND window, I return DXGI_ERROR_NOT_FOUND; }
+static HRESULT dxgi_swapchain_resize_target(IDXGISwapChain1 *iface, + const DXGI_SWAP_CHAIN_DESC *desc, const DXGI_MODE_DESC *mode) +{ + RECT original_window_rect, window_rect; + HWND window = desc->OutputWindow; + HRESULT hr; + + if (!mode) + { + WARN("Invalid pointer.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + TRACE("Mode: %s.\n", debug_dxgi_mode(mode)); + + if (mode->Scaling) + FIXME("Ignoring scaling %#x.\n", mode->Scaling); + + if (desc->Windowed) + { + SetRect(&window_rect, 0, 0, mode->Width, mode->Height); + AdjustWindowRectEx(&window_rect, + GetWindowLongW(window, GWL_STYLE), FALSE, + GetWindowLongW(window, GWL_EXSTYLE)); + SetRect(&window_rect, 0, 0, + window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); + GetWindowRect(window, &original_window_rect); + OffsetRect(&window_rect, original_window_rect.left, original_window_rect.top); + } + else + { + DXGI_MODE_DESC actual_mode; + IDXGIOutput *target; + + if (FAILED(hr = IDXGISwapChain1_GetContainingOutput(iface, &target))) + { + WARN("Failed to get output, hr %#x.\n", hr); + return hr; + } + + if (desc->Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) + { + actual_mode = *mode; + hr = dxgi_output_set_display_mode(target, &actual_mode); + } + else + { + hr = dxgi_output_get_display_mode(target, &actual_mode); + } + + IDXGIOutput_Release(target); + + if (FAILED(hr)) + return hr; + + SetRect(&window_rect, 0, 0, actual_mode.Width, actual_mode.Height); + } + + MoveWindow(window, window_rect.left, window_rect.top, + window_rect.right - window_rect.left, window_rect.bottom - window_rect.top, TRUE); + + return S_OK; +} + static HWND d3d11_swapchain_get_hwnd(struct d3d11_swapchain *swapchain) { struct wined3d_swapchain_desc wined3d_desc; @@ -507,25 +571,13 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeBuffers(IDXGISwapChain1 * static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeTarget(IDXGISwapChain1 *iface, const DXGI_MODE_DESC *target_mode_desc) { - struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); - struct wined3d_display_mode mode; + struct DXGI_SWAP_CHAIN_DESC swap_chain_desc;
TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc);
- if (!target_mode_desc) - { - WARN("Invalid pointer.\n"); - return DXGI_ERROR_INVALID_CALL; - } - - TRACE("Mode: %s.\n", debug_dxgi_mode(target_mode_desc)); - - if (target_mode_desc->Scaling) - FIXME("Ignoring scaling %#x.\n", target_mode_desc->Scaling); - - wined3d_display_mode_from_dxgi(&mode, target_mode_desc); + d3d11_swapchain_GetDesc(iface, &swap_chain_desc);
- return wined3d_swapchain_resize_target(swapchain->wined3d_swapchain, &mode); + return dxgi_swapchain_resize_target(iface, &swap_chain_desc, target_mode_desc); }
static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapChain1 *iface, IDXGIOutput **output) diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index b75aead..8aa8b92 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1361,64 +1361,6 @@ static HRESULT wined3d_swapchain_set_display_mode(struct wined3d_swapchain *swap return WINED3D_OK; }
-HRESULT CDECL wined3d_swapchain_resize_target(struct wined3d_swapchain *swapchain, - const struct wined3d_display_mode *mode) -{ - struct wined3d_display_mode actual_mode; - RECT original_window_rect, window_rect; - struct wined3d_device *device; - HWND window; - HRESULT hr; - - TRACE("swapchain %p, mode %p.\n", swapchain, mode); - - wined3d_mutex_lock(); - - device = swapchain->device; - window = swapchain->device_window; - - if (swapchain->desc.windowed) - { - SetRect(&window_rect, 0, 0, mode->width, mode->height); - AdjustWindowRectEx(&window_rect, - GetWindowLongW(window, GWL_STYLE), FALSE, - GetWindowLongW(window, GWL_EXSTYLE)); - SetRect(&window_rect, 0, 0, - window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); - GetWindowRect(window, &original_window_rect); - OffsetRect(&window_rect, original_window_rect.left, original_window_rect.top); - } - else if (swapchain->desc.flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) - { - actual_mode = *mode; - if (FAILED(hr = wined3d_swapchain_set_display_mode(swapchain, &actual_mode))) - { - wined3d_mutex_unlock(); - return hr; - } - SetRect(&window_rect, 0, 0, actual_mode.width, actual_mode.height); - } - else - { - if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, - &actual_mode, NULL))) - { - ERR("Failed to get display mode, hr %#x.\n", hr); - wined3d_mutex_unlock(); - return hr; - } - - SetRect(&window_rect, 0, 0, actual_mode.width, actual_mode.height); - } - - wined3d_mutex_unlock(); - - MoveWindow(window, window_rect.left, window_rect.top, - window_rect.right - window_rect.left, window_rect.bottom - window_rect.top, TRUE); - - return WINED3D_OK; -} - HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapchain, const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode) { diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 59f99c9..904bb34 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -274,7 +274,6 @@ @ cdecl wined3d_swapchain_incref(ptr) @ cdecl wined3d_swapchain_present(ptr ptr ptr ptr long long) @ cdecl wined3d_swapchain_resize_buffers(ptr long long long long long long) -@ cdecl wined3d_swapchain_resize_target(ptr ptr) @ cdecl wined3d_swapchain_set_fullscreen(ptr ptr ptr) @ cdecl wined3d_swapchain_set_gamma_ramp(ptr long ptr) @ cdecl wined3d_swapchain_set_palette(ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index abef3f0..d1d3ca4 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2690,8 +2690,6 @@ HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain, c HRESULT __cdecl wined3d_swapchain_resize_buffers(struct wined3d_swapchain *swapchain, unsigned int buffer_count, unsigned int width, unsigned int height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality); -HRESULT __cdecl wined3d_swapchain_resize_target(struct wined3d_swapchain *swapchain, - const struct wined3d_display_mode *mode); HRESULT __cdecl wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapchain, const struct wined3d_swapchain_desc *desc, const struct wined3d_display_mode *mode); HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain,
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/swapchain.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 3bf4202..b7a3cc0 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2287,9 +2287,13 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(IDXGISwapChain3 * static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeTarget(IDXGISwapChain3 *iface, const DXGI_MODE_DESC *target_mode_desc) { - FIXME("iface %p, target_mode_desc %p stub!\n", iface, target_mode_desc); + struct DXGI_SWAP_CHAIN_DESC swap_chain_desc;
- return E_NOTIMPL; + TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc); + + d3d12_swapchain_GetDesc(iface, &swap_chain_desc); + + return dxgi_swapchain_resize_target((IDXGISwapChain1 *)iface, &swap_chain_desc, target_mode_desc); }
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapChain3 *iface,
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/wined3d/device.c | 81 +++++++++++++++++++--------------- dlls/wined3d/wined3d.spec | 3 ++ dlls/wined3d/wined3d_private.h | 5 +-- include/wine/wined3d.h | 12 +++++ 4 files changed, 61 insertions(+), 40 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index d35a064..7acf70a 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -927,10 +927,9 @@ static LONG fullscreen_exstyle(LONG exstyle) return exstyle; }
-HRESULT CDECL wined3d_device_setup_fullscreen_window(struct wined3d_device *device, +HRESULT CDECL wined3d_window_setup_fullscreen(struct wined3d_window_state *state, HWND window, unsigned int w, unsigned int h) { - BOOL filter_messages; LONG style, exstyle;
TRACE("Setting up window %p for fullscreen mode.\n", window); @@ -941,42 +940,48 @@ HRESULT CDECL wined3d_device_setup_fullscreen_window(struct wined3d_device *devi return WINED3DERR_NOTAVAILABLE; }
- if (device->style || device->exStyle) + if (state->style || state->exStyle) { ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n", - window, device->style, device->exStyle); + window, state->style, state->exStyle); }
- device->style = GetWindowLongW(window, GWL_STYLE); - device->exStyle = GetWindowLongW(window, GWL_EXSTYLE); + state->style = GetWindowLongW(window, GWL_STYLE); + state->exStyle = GetWindowLongW(window, GWL_EXSTYLE);
- style = fullscreen_style(device->style); - exstyle = fullscreen_exstyle(device->exStyle); + style = fullscreen_style(state->style); + exstyle = fullscreen_exstyle(state->exStyle);
TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n", - device->style, device->exStyle, style, exstyle); - - filter_messages = device->filter_messages; - device->filter_messages = TRUE; + state->style, state->exStyle, style, exstyle);
SetWindowLongW(window, GWL_STYLE, style); SetWindowLongW(window, GWL_EXSTYLE, exstyle); SetWindowPos(window, HWND_TOPMOST, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
- device->filter_messages = filter_messages; - return WINED3D_OK; }
-void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window, +HRESULT CDECL wined3d_device_setup_fullscreen_window(struct wined3d_device *device, + HWND window, unsigned int w, unsigned int h) +{ + BOOL filter_messages; + HRESULT hr; + filter_messages = device->filter_messages; + device->filter_messages = TRUE; + hr = wined3d_window_setup_fullscreen(&device->window_state, window, w, h); + device->filter_messages = filter_messages; + return hr; +} + +void CDECL wined3d_window_restore_from_fullscreen(struct wined3d_window_state *state, HWND window, const RECT *window_rect) { unsigned int window_pos_flags = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE; - BOOL filter_messages; LONG style, exstyle; RECT rect = {0};
- if (!device->style && !device->exStyle) + if (!state->style && !state->exStyle) return;
style = GetWindowLongW(window, GWL_STYLE); @@ -988,23 +993,20 @@ void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *devic * preserve the current status of these flags (i.e. don't restore them) to * more closely emulate the behavior of Direct3D, which leaves these flags * alone when returning to windowed mode. */ - device->style ^= (device->style ^ style) & WS_VISIBLE; - device->exStyle ^= (device->exStyle ^ exstyle) & WS_EX_TOPMOST; + state->style ^= (state->style ^ style) & WS_VISIBLE; + state->exStyle ^= (state->exStyle ^ exstyle) & WS_EX_TOPMOST;
TRACE("Restoring window style of window %p to %08x, %08x.\n", - window, device->style, device->exStyle); - - filter_messages = device->filter_messages; - device->filter_messages = TRUE; + window, state->style, state->exStyle);
/* Only restore the style if the application didn't modify it during the * fullscreen phase. Some applications change it before calling Reset() * when switching between windowed and fullscreen modes (HL2), some * depend on the original style (Eve Online). */ - if (style == fullscreen_style(device->style) && exstyle == fullscreen_exstyle(device->exStyle)) + if (style == fullscreen_style(state->style) && exstyle == fullscreen_exstyle(state->exStyle)) { - SetWindowLongW(window, GWL_STYLE, device->style); - SetWindowLongW(window, GWL_EXSTYLE, device->exStyle); + SetWindowLongW(window, GWL_STYLE, state->style); + SetWindowLongW(window, GWL_EXSTYLE, state->exStyle); }
if (window_rect) @@ -1014,11 +1016,18 @@ void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *devic SetWindowPos(window, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, window_pos_flags);
- device->filter_messages = filter_messages; - /* Delete the old values. */ - device->style = 0; - device->exStyle = 0; + state->style = 0; + state->exStyle = 0; +} + +void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window, + const RECT *window_rect) +{ + BOOL filter_messages = device->filter_messages; + device->filter_messages = TRUE; + wined3d_window_restore_from_fullscreen(&device->window_state, window, window_rect); + device->filter_messages = filter_messages; }
HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window) @@ -5538,19 +5547,19 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, } else if (!swapchain_desc->windowed) { - DWORD style = device->style; - DWORD exStyle = device->exStyle; + DWORD style = device->window_state.style; + DWORD exStyle = device->window_state.exStyle; /* If we're in fullscreen, and the mode wasn't changed, we have to get the window back into * the right position. Some applications(Battlefield 2, Guild Wars) move it and then call * Reset to clear up their mess. Guild Wars also loses the device during that. */ - device->style = 0; - device->exStyle = 0; + device->window_state.style = 0; + device->window_state.exStyle = 0; wined3d_device_setup_fullscreen_window(device, swapchain->device_window, swapchain_desc->backbuffer_width, swapchain_desc->backbuffer_height); - device->style = style; - device->exStyle = exStyle; + device->window_state.style = style; + device->window_state.exStyle = exStyle; }
if (FAILED(hr = wined3d_swapchain_resize_buffers(swapchain, swapchain_desc->backbuffer_count, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 904bb34..b51e1d0 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -313,4 +313,7 @@ @ cdecl wined3d_vertex_declaration_get_parent(ptr) @ cdecl wined3d_vertex_declaration_incref(ptr)
+@ cdecl wined3d_window_setup_fullscreen(ptr ptr long long) +@ cdecl wined3d_window_restore_from_fullscreen(ptr ptr ptr) + @ cdecl wined3d_extract_shader_input_signature_from_dxbc(ptr ptr long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b6f4b67..6f1b9a2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3150,10 +3150,7 @@ struct wined3d_device struct wined3d_device_parent *device_parent; struct wined3d *wined3d; struct wined3d_adapter *adapter; - - /* Window styles to restore when switching fullscreen mode */ - LONG style; - LONG exStyle; + struct wined3d_window_state window_state;
const struct wined3d_shader_backend_ops *shader_backend; void *shader_priv; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index d1d3ca4..e12c9d3 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2171,6 +2171,13 @@ struct wined3d_private_data } content; };
+struct wined3d_window_state +{ + /* Window styles to restore when switching fullscreen mode */ + LONG style; + LONG exStyle; +}; + typedef HRESULT (CDECL *wined3d_device_reset_cb)(struct wined3d_resource *resource);
void __stdcall wined3d_mutex_lock(void); @@ -2756,6 +2763,11 @@ ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaratio HRESULT __cdecl wined3d_extract_shader_input_signature_from_dxbc(struct wined3d_shader_signature *signature, const void *byte_code, SIZE_T byte_code_size);
+void __cdecl wined3d_window_restore_from_fullscreen(struct wined3d_window_state *fullscreen, HWND window, + const RECT *window_rect); +HRESULT __cdecl wined3d_window_setup_fullscreen(struct wined3d_window_state *fullscreen, + HWND window, unsigned int w, unsigned int h); + /* Return the integer base-2 logarithm of x. Undefined for x == 0. */ static inline unsigned int wined3d_log2i(unsigned int x) {
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/swapchain.c | 144 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 4 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index b7a3cc0..457d187 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -1085,8 +1085,12 @@ struct d3d12_swapchain IWineDXGIFactory *factory;
HWND window; + IDXGIOutput *target; DXGI_SWAP_CHAIN_DESC1 desc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc; + struct wined3d_window_state window_state; + DXGI_MODE_DESC original_mode; + RECT orig_window_rect; };
static DXGI_FORMAT dxgi_format_from_vk_format(VkFormat vk_format) @@ -2178,17 +2182,122 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetBuffer(IDXGISwapChain3 *ifac static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreenState(IDXGISwapChain3 *iface, BOOL fullscreen, IDXGIOutput *target) { - FIXME("iface %p, fullscreen %#x, target %p stub!\n", iface, fullscreen, target); + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc = &swapchain->fullscreen_desc; + const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc = &swapchain->desc; + HWND window = swapchain->window; + DXGI_MODE_DESC actual_mode; + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target); + + if (!fullscreen && target) + { + WARN("Invalid call.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + if (target) + { + IDXGIOutput_AddRef(target); + } + else if (FAILED(hr = IDXGISwapChain3_GetContainingOutput(iface, &target))) + { + WARN("Failed to get default target output for swapchain, hr %#x.\n", hr); + return hr; + } + + wined3d_mutex_lock(); + + if (swapchain_desc->Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) + { + if (fullscreen) + { + actual_mode.Width = swapchain_desc->Width; + actual_mode.Height = swapchain_desc->Height; + actual_mode.RefreshRate = fullscreen_desc->RefreshRate; + actual_mode.Format = swapchain_desc->Format; + actual_mode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + } + else + { + actual_mode = swapchain->original_mode; + } + + if (FAILED(hr = dxgi_output_set_display_mode(target, &actual_mode))) + goto release; + } + else + { + if (FAILED(hr = dxgi_output_get_display_mode(target, &actual_mode))) + { + ERR("Failed to get display mode, hr %#x.\n", hr); + hr = DXGI_ERROR_INVALID_CALL; + goto release; + } + } + + if (fullscreen) + { + if (fullscreen_desc->Windowed) + { + if (FAILED(hr = wined3d_window_setup_fullscreen(&swapchain->window_state, + window, actual_mode.Width, actual_mode.Height))) + goto release; + } + else + { + /* Fullscreen -> fullscreen mode change */ + MoveWindow(window, 0, 0, actual_mode.Width, actual_mode.Height, TRUE); + ShowWindow(window, SW_SHOW); + } + } + else if (!fullscreen_desc->Windowed) + { + /* Fullscreen -> windowed switch */ + wined3d_window_restore_from_fullscreen(&swapchain->window_state, window, &swapchain->orig_window_rect); + } + + wined3d_mutex_unlock(); + fullscreen_desc->Windowed = !fullscreen; + + if (!fullscreen) + { + IDXGIOutput_Release(target); + target = NULL; + } + + if (swapchain->target) + IDXGIOutput_Release(swapchain->target); + swapchain->target = target; + + return S_OK; + +release: + wined3d_mutex_unlock(); + IDXGIOutput_Release(target); + + return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; }
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetFullscreenState(IDXGISwapChain3 *iface, BOOL *fullscreen, IDXGIOutput **target) { - FIXME("iface %p, fullscreen %p, target %p stub!\n", iface, fullscreen, target); + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
- return E_NOTIMPL; + TRACE("iface %p, fullscreen %p, target %p.\n", iface, fullscreen, target); + + if (fullscreen) + *fullscreen = !swapchain->fullscreen_desc.Windowed; + + if (target) + { + *target = swapchain->target; + if (*target) + IDXGIOutput_AddRef(*target); + } + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetDesc(IDXGISwapChain3 *iface, DXGI_SWAP_CHAIN_DESC *desc) @@ -2306,6 +2415,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh
TRACE("iface %p, output %p.\n", iface, output);
+ if (swapchain->target) + { + IDXGIOutput_AddRef(*output = swapchain->target); + return S_OK; + } + device_parent = vkd3d_get_device_parent(swapchain->device);
if (SUCCEEDED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter))) @@ -2752,6 +2867,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI swapchain->refcount = 1;
swapchain->window = window; + GetWindowRect(window, &swapchain->orig_window_rect); swapchain->desc = *swapchain_desc; swapchain->fullscreen_desc = *fullscreen_desc;
@@ -2865,6 +2981,7 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu DXGI_SWAP_CHAIN_FULLSCREEN_DESC default_fullscreen_desc; struct d3d12_swapchain *object; ID3D12Device *device; + IDXGIOutput *output; HRESULT hr;
if (swapchain_desc->Format == DXGI_FORMAT_UNKNOWN) @@ -2895,11 +3012,30 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu return hr; }
+ if (FAILED(hr = d3d12_swapchain_GetContainingOutput(&object->IDXGISwapChain3_iface, &output))) + { + ERR("Failed to get containing output, hr %#x.\n", hr); + goto cleanup; + } + + hr = dxgi_output_get_display_mode(output, &object->original_mode); + IDXGIOutput_Release(output); + if (FAILED(hr)) + { + ERR("Failed to get current display mode, hr %#x.\n", hr); + goto cleanup; + } + TRACE("Created swapchain %p.\n", object);
*swapchain = (IDXGISwapChain1 *)&object->IDXGISwapChain3_iface;
return S_OK; + +cleanup: + d3d12_swapchain_destroy(object); + heap_free(object); + return hr; }
#else
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index d8176bb..aae829d 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -395,17 +395,13 @@ static void check_swapchain_fullscreen_state_(unsigned int line, IDXGISwapChain if (!swapchain_desc.Windowed && expected_state->fullscreen) { IDXGIAdapter *adapter; - IDXGIDevice *device; - - hr = IDXGISwapChain_GetDevice(swapchain, &IID_IDXGIDevice, (void **)&device); - ok_(__FILE__, line)(SUCCEEDED(hr), "GetDevice failed, hr %#x.\n", hr); - hr = IDXGIDevice_GetAdapter(device, &adapter); - ok_(__FILE__, line)(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr); - IDXGIDevice_Release(device);
hr = IDXGISwapChain_GetContainingOutput(swapchain, &containing_output); ok_(__FILE__, line)(SUCCEEDED(hr), "GetContainingOutput failed, hr %#x.\n", hr);
+ hr = IDXGIOutput_GetParent(containing_output, &IID_IDXGIAdapter, (void **)&adapter); + ok_(__FILE__, line)(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr); + check_output_equal_(line, target, expected_state->target); ok_(__FILE__, line)(target == containing_output, "Got target %p, expected %p.\n", target, containing_output); @@ -2688,14 +2684,12 @@ static void test_fullscreen_resize_target(IDXGISwapChain *swapchain, IDXGIOutput_Release(target); }
-static void test_resize_target(void) +static void test_resize_target(IUnknown *device, BOOL is_d3d12) { struct swapchain_fullscreen_state initial_state, expected_state; DXGI_SWAP_CHAIN_DESC swapchain_desc; IDXGISwapChain *swapchain; IDXGIFactory *factory; - IDXGIAdapter *adapter; - IDXGIDevice *device; unsigned int i; ULONG refcount; HRESULT hr; @@ -2723,17 +2717,7 @@ static void test_resize_target(void) {{10, 10}, FALSE, TRUE, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH}, };
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } - - hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr); - - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr); + get_factory(device, is_d3d12, &factory);
swapchain_desc.BufferDesc.Width = 800; swapchain_desc.BufferDesc.Height = 600; @@ -2745,9 +2729,9 @@ static void test_resize_target(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.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;
for (i = 0; i < ARRAY_SIZE(tests); ++i) @@ -2829,11 +2813,8 @@ static void test_resize_target(void) DestroyWindow(swapchain_desc.OutputWindow); }
- IDXGIAdapter_Release(adapter); - refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %u references left.\n", refcount); + ok(refcount == !is_d3d12, "Got unexpected refcount %u.\n", refcount); }
static LRESULT CALLBACK resize_target_wndproc(HWND hwnd, unsigned int message, WPARAM wparam, LPARAM lparam) @@ -5718,13 +5699,13 @@ START_TEST(dxgi) test_create_swapchain(); test_set_fullscreen(); test_default_fullscreen_target_output(); - test_resize_target(); test_inexact_modes(); test_gamma_control(); test_swapchain_parameters(); test_swapchain_window_messages(); test_swapchain_window_styles(); test_window_association(); + run_on_d3d10(test_resize_target); run_on_d3d10(test_swapchain_resize); run_on_d3d10(test_swapchain_present); run_on_d3d10(test_swapchain_backbuffer_index); @@ -5746,6 +5727,7 @@ START_TEST(dxgi) ID3D12Debug_Release(debug); }
+ run_on_d3d12(test_resize_target); run_on_d3d12(test_swapchain_resize); run_on_d3d12(test_swapchain_present); run_on_d3d12(test_swapchain_backbuffer_index);
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 84 +++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 41 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index aae829d..b2c8773 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -2295,28 +2295,18 @@ static void test_swapchain_fullscreen_state(IDXGISwapChain *swapchain, heap_free(output_monitor_info); }
-static void test_set_fullscreen(void) +static void test_set_fullscreen(IUnknown *device, BOOL is_d3d12) { struct swapchain_fullscreen_state initial_state; DXGI_SWAP_CHAIN_DESC swapchain_desc; IDXGISwapChain *swapchain; IDXGIFactory *factory; IDXGIAdapter *adapter; - IDXGIDevice *device; + IDXGIOutput *output; ULONG refcount; HRESULT hr;
- if (!(device = create_device(0))) - { - skip("Failed to create device.\n"); - return; - } - - hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr); - - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr); + get_factory(device, is_d3d12, &factory);
swapchain_desc.BufferDesc.Width = 800; swapchain_desc.BufferDesc.Height = 600; @@ -2328,16 +2318,28 @@ static void test_set_fullscreen(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 = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); 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;
memset(&initial_state, 0, sizeof(initial_state)); capture_fullscreen_state(&initial_state.fullscreen_state, swapchain_desc.OutputWindow); hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain); ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr); + hr = IDXGISwapChain_GetContainingOutput(swapchain, &output); + ok(SUCCEEDED(hr) || broken(hr == DXGI_ERROR_UNSUPPORTED), /* Win 7 testbot */ + "GetContainingOutput failed, hr %#x.\n", hr); + if (FAILED(hr)) + { + skip("Could not get output.\n"); + goto done; + } + hr = IDXGIOutput_GetParent(output, &IID_IDXGIAdapter, (void **)&adapter); + ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr); + IDXGIOutput_Release(output); + check_swapchain_fullscreen_state(swapchain, &initial_state); hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL); ok(SUCCEEDED(hr) || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE @@ -2346,7 +2348,7 @@ static void test_set_fullscreen(void) if (FAILED(hr)) { skip("Could not change fullscreen state.\n"); - goto done; + goto free_adapter; } hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); @@ -2406,17 +2408,16 @@ static void test_set_fullscreen(void) check_swapchain_fullscreen_state(swapchain, &initial_state); test_swapchain_fullscreen_state(swapchain, adapter, &initial_state);
+free_adapter: + IDXGIAdapter_Release(adapter); done: refcount = IDXGISwapChain_Release(swapchain); ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount); check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state); DestroyWindow(swapchain_desc.OutputWindow);
- IDXGIAdapter_Release(adapter); - refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %u references left.\n", refcount); + ok(refcount == !is_d3d12, "Got unexpected refcount %u.\n", refcount); }
static void test_default_fullscreen_target_output(void) @@ -4136,7 +4137,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) 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); + 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]); @@ -4144,23 +4145,23 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) 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); + ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr); + ok(fullscreen, "Test %u: Got unexpected fullscreen status.\n", i); + 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); + ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr); + 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); + 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. */ @@ -4179,11 +4180,11 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) * 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); + 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); + ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr); + 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]); @@ -4198,8 +4199,8 @@ static void test_swapchain_present(IUnknown *device, BOOL 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); + ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr); + 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); @@ -4212,7 +4213,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) * 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); + 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);
@@ -4224,7 +4225,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_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); + 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); @@ -4248,7 +4249,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) * 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); + 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); @@ -4283,7 +4284,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_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); + 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); @@ -4293,7 +4294,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) 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); + 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); } @@ -5534,11 +5535,11 @@ static void test_output_ownership(IUnknown *device, BOOL is_d3d12) skip("Failed to change fullscreen state.\n"); goto done; } - todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + 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, "Got unexpected fullscreen state.\n"); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(fullscreen, "Got unexpected fullscreen state.\n"); if (is_d3d12) wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_SUCCESS, FALSE); else @@ -5697,7 +5698,6 @@ START_TEST(dxgi)
/* These tests use full-screen swapchains, so shouldn't run in parallel. */ test_create_swapchain(); - test_set_fullscreen(); test_default_fullscreen_target_output(); test_inexact_modes(); test_gamma_control(); @@ -5705,6 +5705,7 @@ START_TEST(dxgi) test_swapchain_window_messages(); test_swapchain_window_styles(); test_window_association(); + run_on_d3d10(test_set_fullscreen); run_on_d3d10(test_resize_target); run_on_d3d10(test_swapchain_resize); run_on_d3d10(test_swapchain_present); @@ -5727,6 +5728,7 @@ START_TEST(dxgi) ID3D12Debug_Release(debug); }
+ run_on_d3d12(test_set_fullscreen); run_on_d3d12(test_resize_target); run_on_d3d12(test_swapchain_resize); run_on_d3d12(test_swapchain_present);
the todo_wines should go away at the same patch that implements the features.
On 6/26/19 11:30 PM, Conor McCarthy wrote:
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com
dlls/dxgi/tests/dxgi.c | 84 +++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 41 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index aae829d..b2c8773 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -2295,28 +2295,18 @@ static void test_swapchain_fullscreen_state(IDXGISwapChain *swapchain, heap_free(output_monitor_info); }
-static void test_set_fullscreen(void) +static void test_set_fullscreen(IUnknown *device, BOOL is_d3d12) { struct swapchain_fullscreen_state initial_state; DXGI_SWAP_CHAIN_DESC swapchain_desc; IDXGISwapChain *swapchain; IDXGIFactory *factory; IDXGIAdapter *adapter;
- IDXGIDevice *device;
- IDXGIOutput *output; ULONG refcount; HRESULT hr;
- if (!(device = create_device(0)))
- {
skip("Failed to create device.\n");
return;
- }
- hr = IDXGIDevice_GetAdapter(device, &adapter);
- ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
- hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
- ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
get_factory(device, is_d3d12, &factory);
swapchain_desc.BufferDesc.Width = 800; swapchain_desc.BufferDesc.Height = 600;
@@ -2328,16 +2318,28 @@ static void test_set_fullscreen(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 = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); 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;
memset(&initial_state, 0, sizeof(initial_state)); capture_fullscreen_state(&initial_state.fullscreen_state, swapchain_desc.OutputWindow); hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain); ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
hr = IDXGISwapChain_GetContainingOutput(swapchain, &output);
ok(SUCCEEDED(hr) || broken(hr == DXGI_ERROR_UNSUPPORTED), /* Win 7 testbot */
"GetContainingOutput failed, hr %#x.\n", hr);
if (FAILED(hr))
{
skip("Could not get output.\n");
goto done;
}
hr = IDXGIOutput_GetParent(output, &IID_IDXGIAdapter, (void **)&adapter);
ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
IDXGIOutput_Release(output);
check_swapchain_fullscreen_state(swapchain, &initial_state); hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL); ok(SUCCEEDED(hr) || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
@@ -2346,7 +2348,7 @@ static void test_set_fullscreen(void) if (FAILED(hr)) { skip("Could not change fullscreen state.\n");
goto done;
} hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);goto free_adapter;
@@ -2406,17 +2408,16 @@ static void test_set_fullscreen(void) check_swapchain_fullscreen_state(swapchain, &initial_state); test_swapchain_fullscreen_state(swapchain, adapter, &initial_state);
+free_adapter:
- IDXGIAdapter_Release(adapter);
done: refcount = IDXGISwapChain_Release(swapchain); ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount); check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state); DestroyWindow(swapchain_desc.OutputWindow);
- IDXGIAdapter_Release(adapter);
- refcount = IDXGIDevice_Release(device);
- ok(!refcount, "Device has %u references left.\n", refcount); refcount = IDXGIFactory_Release(factory);
- ok(!refcount, "Factory has %u references left.\n", refcount);
- ok(refcount == !is_d3d12, "Got unexpected refcount %u.\n", refcount);
}
static void test_default_fullscreen_target_output(void) @@ -4136,7 +4137,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) 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);
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]);
@@ -4144,23 +4145,23 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) 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);
ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
ok(fullscreen, "Test %u: Got unexpected fullscreen status.\n", i);
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);
ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
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);
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. */
@@ -4179,11 +4180,11 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) * 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);
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);
ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
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]);
@@ -4198,8 +4199,8 @@ static void test_swapchain_present(IUnknown *device, BOOL 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);
ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
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);
@@ -4212,7 +4213,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) * 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);
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);
@@ -4224,7 +4225,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_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);
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);
@@ -4248,7 +4249,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) * 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);
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);
@@ -4283,7 +4284,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_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);
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);
@@ -4293,7 +4294,7 @@ static void test_swapchain_present(IUnknown *device, BOOL is_d3d12) 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);
}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);
@@ -5534,11 +5535,11 @@ static void test_output_ownership(IUnknown *device, BOOL is_d3d12) skip("Failed to change fullscreen state.\n"); goto done; }
- todo_wine_if(is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- 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, "Got unexpected fullscreen state.\n");
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ok(fullscreen, "Got unexpected fullscreen state.\n"); if (is_d3d12) wait_vidpn_exclusive_ownership(&check_ownership_desc, STATUS_SUCCESS, FALSE); else
@@ -5697,7 +5698,6 @@ START_TEST(dxgi)
/* These tests use full-screen swapchains, so shouldn't run in parallel. */ test_create_swapchain();
- test_set_fullscreen(); test_default_fullscreen_target_output(); test_inexact_modes(); test_gamma_control();
@@ -5705,6 +5705,7 @@ START_TEST(dxgi) test_swapchain_window_messages(); test_swapchain_window_styles(); test_window_association();
- run_on_d3d10(test_set_fullscreen); run_on_d3d10(test_resize_target); run_on_d3d10(test_swapchain_resize); run_on_d3d10(test_swapchain_present);
@@ -5727,6 +5728,7 @@ START_TEST(dxgi) ID3D12Debug_Release(debug); }
- run_on_d3d12(test_set_fullscreen); run_on_d3d12(test_resize_target); run_on_d3d12(test_swapchain_resize); run_on_d3d12(test_swapchain_present);