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
On 2019/6/26 20:07, Conor McCarthy wrote:
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;
}
Hi Conor,
My dxgi patch yesterday have some todo_wines for d3d12 Set/GetFullscreenState. Now they should start succeeding and you need to remove those todo_wines.
Thanks, Zhiyi
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
June 26, 2019 11:26 PM, "Zhiyi Zhang" zzhang@codeweavers.com wrote:
Hi Conor,
My dxgi patch yesterday have some todo_wines for d3d12 Set/GetFullscreenState. Now they should start succeeding and you need to remove those todo_wines.
Thanks, Zhiyi
Hi Zhiyi,
The instances of todo_wine_if(is_d3d12) in test_swapchain_present() and test_output_ownership() ? Thanks, I'll remove them and retest.
Conor
On 6/26/19 9:42 PM, cmccarthy@codeweavers.com wrote:
June 26, 2019 11:26 PM, "Zhiyi Zhang" zzhang@codeweavers.com wrote:
Hi Conor,
My dxgi patch yesterday have some todo_wines for d3d12 Set/GetFullscreenState. Now they should start succeeding and you need to remove those todo_wines.
Thanks, Zhiyi
Hi Zhiyi,
The instances of todo_wine_if(is_d3d12) in test_swapchain_present() and test_output_ownership() ?
Yes. Thanks.
Thanks, I'll remove them and retest.
Conor
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);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=54147
Your paranoid android.
=== w2008s64 (32 bit report) ===
dxgi: dxgi.c:4813: Test failed: Got unexpected message 0x1a, hwnd 001300C6, wparam 0x18, lparam 0x7e528.
=== w8adm (32 bit report) ===
dxgi: dxgi.c:4813: Test failed: Got unexpected message 0x31f, hwnd 001E022A, wparam 0x1, lparam 0.
=== w2008s64 (64 bit report) ===
dxgi: dxgi.c:4813: Test failed: Got unexpected message 0x1a, hwnd 00000000001800FA, wparam 0x18, lparam 0x22f998.
=== w1064v1507 (64 bit report) ===
dxgi: dxgi.c:4813: Test failed: Got unexpected message 0x31f, hwnd 000000000010021E, wparam 0x1, lparam 0.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 44 ++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index aae829d..612ba23 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) @@ -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);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=54148
Your paranoid android.
=== w1064v1809 (32 bit report) ===
dxgi: dxgi.c:2390: Test failed: Got unexpected hr 0x887a0022. dxgi.c:2393: Test failed: Got unexpected hr 0x887a0022.
=== w1064v1809 (64 bit report) ===
dxgi: dxgi.c:4814: Test failed: Got unexpected message 0x31f, hwnd 00000000001602F2, wparam 0x1, lparam 0.
On 2019/6/26 20:07, Conor McCarthy wrote:
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com
dlls/dxgi/tests/dxgi.c | 44 ++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index aae829d..612ba23 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);
I think you can avoid free_adapter label.
+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) @@ -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);
June 26, 2019 11:30 PM, "Zhiyi Zhang" zzhang@codeweavers.com wrote:
- 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);
I think you can avoid free_adapter label.
+free_adapter:
- IDXGIAdapter_Release(adapter);
done:
adapter is initialized later because of the switch to a multi-device test. It will crash if not skipped.
Conor