Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/dxgi_private.h | 2 ++ dlls/dxgi/output.c | 61 ++++++++++++++++++++++++++++++++++++++ dlls/dxgi/swapchain.c | 62 ++++++++++++++++++++++++++++++++++++--- dlls/wined3d/swapchain.c | 58 ------------------------------------ dlls/wined3d/wined3d.spec | 1 - include/wine/wined3d.h | 2 -- 6 files changed, 121 insertions(+), 65 deletions(-)
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index 553eace..9cb43b8 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_set_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *target_mode_desc) DECLSPEC_HIDDEN; +HRESULT dxgi_output_get_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *mode_desc) DECLSPEC_HIDDEN;
/* IDXGIAdapter */ struct dxgi_adapter diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index 123dee8..f64f425 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -539,3 +539,64 @@ HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **ou dxgi_output_init(*output, adapter); return S_OK; } + +HRESULT dxgi_output_set_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *target_mode_desc) +{ + struct wined3d_display_mode wined3d_mode; + struct dxgi_adapter *adapter; + struct dxgi_output *target; + struct wined3d *wined3d; + HRESULT hr; + + target = impl_from_IDXGIOutput4((IDXGIOutput4 *)iface); + adapter = target->adapter; + wined3d = adapter->factory->wined3d; + + wined3d_display_mode_from_dxgi(&wined3d_mode, target_mode_desc); + + 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(target_mode_desc, &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; +} + +HRESULT dxgi_output_get_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *mode_desc) +{ + struct wined3d_display_mode wined3d_mode; + struct dxgi_adapter *adapter; + struct dxgi_output *target; + struct wined3d *wined3d; + HRESULT hr; + + target = impl_from_IDXGIOutput4((IDXGIOutput4 *)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_desc, &wined3d_mode); + + TRACE("Returning %s.\n", debug_dxgi_mode(mode_desc)); + + return S_OK; +} diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 4f01d9c..b060a30 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -501,11 +501,65 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeBuffers(IDXGISwapChain1 * return hr; }
+static HRESULT dxgi_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; + + TRACE("iface %p, desc %p, mode %p.\n", iface, desc, mode); + + 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 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);
@@ -520,9 +574,9 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeTarget(IDXGISwapChain1 *i 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_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 8d6306e..c6bab5a 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1364,64 +1364,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 | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index b060a30..86659d4 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2286,9 +2286,24 @@ 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); + + 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); + + d3d12_swapchain_GetDesc(iface, &swap_chain_desc); + + return dxgi_resize_target((IDXGISwapChain1 *)iface, &swap_chain_desc, target_mode_desc); }
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapChain3 *iface,
On Mon, Jun 24, 2019 at 4:23 PM Conor McCarthy cmccarthy@codeweavers.com wrote:
- 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);
The lines above should be moved to the dxgi_resize_target() helper.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/wined3d/device.c | 214 +++++++++++++++++---------------- dlls/wined3d/wined3d.spec | 3 + dlls/wined3d/wined3d_private.h | 5 +- include/wine/wined3d.h | 12 ++ 4 files changed, 127 insertions(+), 107 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index d35a064..2e2da32 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -910,115 +910,24 @@ static void destroy_default_samplers(struct wined3d_device *device, struct wined device->null_sampler = NULL; }
-static LONG fullscreen_style(LONG style) -{ - /* Make sure the window is managed, otherwise we won't get keyboard input. */ - style |= WS_POPUP | WS_SYSMENU; - style &= ~(WS_CAPTION | WS_THICKFRAME); - - return style; -} - -static LONG fullscreen_exstyle(LONG exstyle) -{ - /* Filter out window decorations. */ - exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); - - return exstyle; -} - HRESULT CDECL wined3d_device_setup_fullscreen_window(struct wined3d_device *device, HWND window, unsigned int w, unsigned int h) { - BOOL filter_messages; - LONG style, exstyle; - - TRACE("Setting up window %p for fullscreen mode.\n", window); - - if (!IsWindow(window)) - { - WARN("%p is not a valid window.\n", window); - return WINED3DERR_NOTAVAILABLE; - } - - if (device->style || device->exStyle) - { - ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n", - window, device->style, device->exStyle); - } - - device->style = GetWindowLongW(window, GWL_STYLE); - device->exStyle = GetWindowLongW(window, GWL_EXSTYLE); - - style = fullscreen_style(device->style); - exstyle = fullscreen_exstyle(device->exStyle); - - TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n", - device->style, device->exStyle, style, exstyle); - - filter_messages = device->filter_messages; + HRESULT hr; + BOOL filter_messages = device->filter_messages; device->filter_messages = TRUE; - - SetWindowLongW(window, GWL_STYLE, style); - SetWindowLongW(window, GWL_EXSTYLE, exstyle); - SetWindowPos(window, HWND_TOPMOST, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); - + hr = wined3d_fullscreen_setup_window(&device->fullscreen_state, window, w, h); device->filter_messages = filter_messages; - - return WINED3D_OK; + return hr; }
void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *device, 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) - return; - - style = GetWindowLongW(window, GWL_STYLE); - exstyle = GetWindowLongW(window, GWL_EXSTYLE); - - /* These flags are set by wined3d_device_setup_fullscreen_window, not the - * application, and we want to ignore them in the test below, since it's - * not the application's fault that they changed. Additionally, we want to - * 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; - - TRACE("Restoring window style of window %p to %08x, %08x.\n", - window, device->style, device->exStyle); - - filter_messages = device->filter_messages; + BOOL filter_messages = device->filter_messages; device->filter_messages = TRUE; - - /* 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)) - { - SetWindowLongW(window, GWL_STYLE, device->style); - SetWindowLongW(window, GWL_EXSTYLE, device->exStyle); - } - - if (window_rect) - rect = *window_rect; - else - window_pos_flags |= (SWP_NOMOVE | SWP_NOSIZE); - SetWindowPos(window, 0, rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, window_pos_flags); - + wined3d_fullscreen_restore_window(&device->fullscreen_state, window, window_rect); device->filter_messages = filter_messages; - - /* Delete the old values. */ - device->style = 0; - device->exStyle = 0; }
HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window) @@ -5538,19 +5447,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->fullscreen_state.style; + DWORD exStyle = device->fullscreen_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->fullscreen_state.style = 0; + device->fullscreen_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->fullscreen_state.style = style; + device->fullscreen_state.exStyle = exStyle; }
if (FAILED(hr = wined3d_swapchain_resize_buffers(swapchain, swapchain_desc->backbuffer_count, @@ -6036,3 +5945,102 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL else return CallWindowProcA(proc, window, message, wparam, lparam); } + +static LONG fullscreen_style(LONG style) +{ + /* Make sure the window is managed, otherwise we won't get keyboard input. */ + style |= WS_POPUP | WS_SYSMENU; + style &= ~(WS_CAPTION | WS_THICKFRAME); + + return style; +} + +static LONG fullscreen_exstyle(LONG exstyle) +{ + /* Filter out window decorations. */ + exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); + + return exstyle; +} + +HRESULT CDECL wined3d_fullscreen_setup_window(struct wined3d_fullscreen_state *fullscreen, + HWND window, unsigned int w, unsigned int h) +{ + LONG style, exstyle; + + TRACE("Setting up window %p for fullscreen mode.\n", window); + + if (!IsWindow(window)) + { + WARN("%p is not a valid window.\n", window); + return WINED3DERR_NOTAVAILABLE; + } + + if (fullscreen->style || fullscreen->exStyle) + { + ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n", + window, fullscreen->style, fullscreen->exStyle); + } + + fullscreen->style = GetWindowLongW(window, GWL_STYLE); + fullscreen->exStyle = GetWindowLongW(window, GWL_EXSTYLE); + + style = fullscreen_style(fullscreen->style); + exstyle = fullscreen_exstyle(fullscreen->exStyle); + + TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n", + fullscreen->style, fullscreen->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); + + return WINED3D_OK; +} + +void CDECL wined3d_fullscreen_restore_window(struct wined3d_fullscreen_state *fullscreen, HWND window, + const RECT *window_rect) +{ + unsigned int window_pos_flags = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE; + LONG style, exstyle; + RECT rect = {0}; + + if (!fullscreen->style && !fullscreen->exStyle) + return; + + style = GetWindowLongW(window, GWL_STYLE); + exstyle = GetWindowLongW(window, GWL_EXSTYLE); + + /* These flags are set by wined3d_device_setup_fullscreen_window, not the + * application, and we want to ignore them in the test below, since it's + * not the application's fault that they changed. Additionally, we want to + * 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. */ + fullscreen->style ^= (fullscreen->style ^ style) & WS_VISIBLE; + fullscreen->exStyle ^= (fullscreen->exStyle ^ exstyle) & WS_EX_TOPMOST; + + TRACE("Restoring window style of window %p to %08x, %08x.\n", + window, fullscreen->style, fullscreen->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(fullscreen->style) && exstyle == fullscreen_exstyle(fullscreen->exStyle)) + { + SetWindowLongW(window, GWL_STYLE, fullscreen->style); + SetWindowLongW(window, GWL_EXSTYLE, fullscreen->exStyle); + } + + if (window_rect) + rect = *window_rect; + else + window_pos_flags |= (SWP_NOMOVE | SWP_NOSIZE); + SetWindowPos(window, 0, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, window_pos_flags); + + /* Delete the old values. */ + fullscreen->style = 0; + fullscreen->exStyle = 0; +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 904bb34..ddb4e56 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -314,3 +314,6 @@ @ cdecl wined3d_vertex_declaration_incref(ptr)
@ cdecl wined3d_extract_shader_input_signature_from_dxbc(ptr ptr long) + +@ cdecl wined3d_fullscreen_setup_window(ptr ptr long long) +@ cdecl wined3d_fullscreen_restore_window(ptr ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8e23653..9d649fe 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_fullscreen_state fullscreen_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..f08383a 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2171,6 +2171,13 @@ struct wined3d_private_data } content; };
+struct wined3d_fullscreen_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_fullscreen_restore_window(struct wined3d_fullscreen_state *fullscreen, HWND window, + const RECT *window_rect); +HRESULT __cdecl wined3d_fullscreen_setup_window(struct wined3d_fullscreen_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) {
On Mon, Jun 24, 2019 at 4:23 PM Conor McCarthy cmccarthy@codeweavers.com wrote:
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com
dlls/wined3d/device.c | 214 +++++++++++++++++---------------- dlls/wined3d/wined3d.spec | 3 + dlls/wined3d/wined3d_private.h | 5 +- include/wine/wined3d.h | 12 ++ 4 files changed, 127 insertions(+), 107 deletions(-)
This patch can be made much smaller. Just put the new functions, e.g. wined3d_fullscreen_setup_window(), in the place where old functions were. In result, you will get a few renames and removal of "filter_messages". Moving functions to the end of the file is not necessary.
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8e23653..9d649fe 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_fullscreen_state fullscreen_state;
The fullscreen_state should probably be moved to wined3d swapchain.
+struct wined3d_fullscreen_state +{
- /* Window styles to restore when switching fullscreen mode */
- LONG style;
- LONG exStyle;
+};
It might be better to not expose implementation details and make wined3d_fullscreen_state opaque.
Perhaps, wined3d_window_state is a better name?
June 25, 2019 9:54 PM, "Józef Kucia" joseph.kucia@gmail.com wrote:
This patch can be made much smaller. Just put the new functions, e.g. wined3d_fullscreen_setup_window(), in the place where old functions were. In result, you will get a few renames and removal of "filter_messages". Moving functions to the end of the file is not necessary.
- /* Window styles to restore when switching fullscreen mode */
- LONG style;
- LONG exStyle;
- struct wined3d_fullscreen_state fullscreen_state;
The fullscreen_state should probably be moved to wined3d swapchain.
I kept wined3d_device_setup_fullscreen_window() and its opposite as wrappers because they are used elsewhere, for example ddraw calls them, but the swapchain pointer in struct ddraw can be null which makes it complicated. Rather than change all calls to these functions it was simpler to make it call a helper that D3D12 can use too.
+struct wined3d_fullscreen_state +{
- /* Window styles to restore when switching fullscreen mode */
- LONG style;
- LONG exStyle;
+};
It might be better to not expose implementation details and make wined3d_fullscreen_state opaque.
D3D12 needs to declare one in d3d12_swapchain. It could be made opaque if dynamically allocated instead, but that seems excessive.
Conor
On Tue, Jun 25, 2019 at 3:29 PM cmccarthy@codeweavers.com wrote:
June 25, 2019 9:54 PM, "Józef Kucia" joseph.kucia@gmail.com wrote:
This patch can be made much smaller. Just put the new functions, e.g. wined3d_fullscreen_setup_window(), in the place where old functions were. In result, you will get a few renames and removal of "filter_messages". Moving functions to the end of the file is not necessary.
- /* Window styles to restore when switching fullscreen mode */
- LONG style;
- LONG exStyle;
- struct wined3d_fullscreen_state fullscreen_state;
The fullscreen_state should probably be moved to wined3d swapchain.
I kept wined3d_device_setup_fullscreen_window() and its opposite as wrappers because they are used elsewhere, for example ddraw calls them, but the swapchain pointer in struct ddraw can be null which makes it complicated. Rather than change all calls to these functions it was simpler to make it call a helper that D3D12 can use too.
Yes, that's fine. You just need to reorder the code slightly in the file to make the patch smaller.
Also, you're probably right that moving the "fullscreen_state" to wined3d_swapchain is not easy.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/swapchain.c | 150 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 4 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 86659d4..c623b95 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -1084,8 +1084,12 @@ struct d3d12_swapchain IWineDXGIFactory *factory;
HWND window; + IDXGIOutput *target; DXGI_SWAP_CHAIN_DESC1 desc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc; + struct wined3d_fullscreen_state fullscreen_state; + DXGI_MODE_DESC original_mode; + RECT orig_window_rect; };
static DXGI_FORMAT dxgi_format_from_vk_format(VkFormat vk_format) @@ -2177,17 +2181,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_fullscreen_setup_window(&swapchain->fullscreen_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_fullscreen_restore_window(&swapchain->fullscreen_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) @@ -2316,6 +2425,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))) @@ -2756,6 +2871,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;
@@ -2862,6 +2978,26 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI return S_OK; }
+static HRESULT d3d12_swapchain_fullscreen_init(struct d3d12_swapchain *swapchain) +{ + IDXGISwapChain3 *iface = &swapchain->IDXGISwapChain3_iface; + IDXGIOutput *output; + HRESULT hr; + + if (FAILED(hr = d3d12_swapchain_GetContainingOutput(iface, &output))) + { + ERR("Failed to get containing output, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = dxgi_output_get_display_mode(output, &swapchain->original_mode))) + ERR("Failed to get current display mode, hr %#x.\n", hr); + + IDXGIOutput_Release(output); + + return hr; +} + HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *queue, HWND window, const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, IDXGISwapChain1 **swapchain) @@ -2899,6 +3035,12 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu return hr; }
+ if(FAILED(hr = d3d12_swapchain_fullscreen_init(object))) + { + heap_free(object); + return hr; + } + TRACE("Created swapchain %p.\n", object);
*swapchain = (IDXGISwapChain1 *)&object->IDXGISwapChain3_iface;
On Mon, Jun 24, 2019 at 4:24 PM Conor McCarthy cmccarthy@codeweavers.com wrote:
static DXGI_FORMAT dxgi_format_from_vk_format(VkFormat vk_format) @@ -2177,17 +2181,122 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetBuffer(IDXGISwapChain3 *ifac static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreenState(IDXGISwapChain3 *iface, BOOL fullscreen, IDXGIOutput *target)
If possible, we would like to share more code with wined3d instead of copying wined3d_swapchain_set_fullscreen() to d3d12_swapchain_SetFullscreenState().
+static HRESULT d3d12_swapchain_fullscreen_init(struct d3d12_swapchain *swapchain) +{
- IDXGISwapChain3 *iface = &swapchain->IDXGISwapChain3_iface;
- IDXGIOutput *output;
- HRESULT hr;
- if (FAILED(hr = d3d12_swapchain_GetContainingOutput(iface, &output)))
- {
ERR("Failed to get containing output, hr %#x.\n", hr);
return hr;
- }
- if (FAILED(hr = dxgi_output_get_display_mode(output, &swapchain->original_mode)))
ERR("Failed to get current display mode, hr %#x.\n", hr);
- IDXGIOutput_Release(output);
- return hr;
+}
This probably should go into d3d12_swapchain_init().
- if(FAILED(hr = d3d12_swapchain_fullscreen_init(object)))
Coding style.
- {
heap_free(object);
return hr;
- }
This introduces a memory leak. All objects in d3d12_swapchain structure are leaked.
June 25, 2019 9:55 PM, "Józef Kucia" joseph.kucia@gmail.com wrote:
If possible, we would like to share more code with wined3d instead of copying wined3d_swapchain_set_fullscreen() to d3d12_swapchain_SetFullscreenState().
I've looked at doing this a couple of times. Some complications:
D3D12 doesn't use adapter_format_from_backbuffer_format(). The wined3d function turns message filtering on/off using wined3d_device. No equivalent of 'swapchain->d3d_mode = actual_mode' exists in the D3D12 version. The original window rect is always restored in DXGI but not wined3d. The Alt+Enter handler in wined3d_hook_proc() calls wined3d_swapchain_set_fullscreen() too.
No doubt it can be made to work through a common helper with some optional parameters. It will probably be a bit messy though. It depends on what's more important.
Conor
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 69c868c..615892f 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -2602,14 +2602,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; @@ -2637,17 +2635,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; @@ -2659,9 +2647,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) @@ -2743,11 +2731,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) @@ -5288,13 +5273,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); @@ -5315,6 +5300,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=54067
Your paranoid android.
=== w2008s64 (32 bit report) ===
dxgi: dxgi.c:4534: Test failed: Got unexpected message 0x46, hwnd 001200FE, wparam 0, lparam 0x27fbb0. dxgi.c:4534: Test failed: Got unexpected message 0x24, hwnd 001200FE, wparam 0, lparam 0x27f930. dxgi.c:4534: Test failed: Got unexpected message 0x1a, hwnd 001200FE, wparam 0x2f, lparam 0x7e528.
=== w1064v1809 (64 bit report) ===
dxgi: dxgi.c:2704: Test failed: GetDevice failed, hr 0x80004002. 0978:dxgi: unhandled exception c0000005 at 0000000000409E97
The commit summary line could be better, e.g. "dxgi/tests: Execute test_resize_target() on D3D12 device", "dxgi/tests: Run resize target tests on D3D12.".
On Mon, Jun 24, 2019 at 4:24 PM Conor McCarthy cmccarthy@codeweavers.com wrote:
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com
dlls/dxgi/tests/dxgi.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-)
This patch introduces test failures on Windows. You need to fix check_swapchain_fullscreen_state_() in this patch.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 45 +++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 27 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 615892f..8e719c4 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -387,17 +387,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); @@ -2023,7 +2019,7 @@ static void test_get_containing_output(void) hr = IDXGISwapChain_GetContainingOutput(swapchain, &output); ok(hr == S_OK || broken(hr == DXGI_ERROR_UNSUPPORTED), "Failed to get containing output, hr %#x.\n", hr); - if (hr == DXGI_ERROR_UNSUPPORTED) + if (hr != S_OK) continue; ok(!!output, "Got unexpected containing output %p.\n", output); hr = IDXGIOutput_GetDesc(output, &output_desc); @@ -2213,28 +2209,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; @@ -2246,16 +2232,22 @@ 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), "GetContainingOutput failed, hr %#x.\n", hr); + 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 @@ -2331,10 +2323,8 @@ done: 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) @@ -5271,7 +5261,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(); @@ -5279,6 +5268,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); @@ -5300,6 +5290,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=54068
Your paranoid android.
=== w7u (32 bit report) ===
dxgi: dxgi.c:2246: Test failed: GetContainingOutput failed, hr 0x887a0004. 0d7c:dxgi: unhandled exception c0000005 at 0040D7CC
=== w7pro64 (32 bit report) ===
dxgi: dxgi.c:2246: Test failed: GetContainingOutput failed, hr 0x887a0004. 0ab0:dxgi: unhandled exception c0000005 at 0040D7CC
=== w7pro64 (64 bit report) ===
dxgi: dxgi.c:2246: Test failed: GetContainingOutput failed, hr 0x887a0004. 0a84:dxgi: unhandled exception c0000005 at 000000000040BEFD
The commit summary line could be better.
On Mon, Jun 24, 2019 at 4:24 PM Conor McCarthy cmccarthy@codeweavers.com wrote:
@@ -2023,7 +2019,7 @@ static void test_get_containing_output(void) hr = IDXGISwapChain_GetContainingOutput(swapchain, &output); ok(hr == S_OK || broken(hr == DXGI_ERROR_UNSUPPORTED), "Failed to get containing output, hr %#x.\n", hr);
if (hr == DXGI_ERROR_UNSUPPORTED)
if (hr != S_OK) continue;
Unrelated change.
The commit summary line is quite inaccurate. One of the following summary lines seem to be much better: * "wined3d: Move wined3d_swapchain_resize_target() to dxgi.", * "dxgi: Move wined3d_swapchain_resize_targe() from wined3d.".
On Mon, Jun 24, 2019 at 4:23 PM Conor McCarthy cmccarthy@codeweavers.com wrote:
HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output) DECLSPEC_HIDDEN; +HRESULT dxgi_output_set_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *target_mode_desc) DECLSPEC_HIDDEN; +HRESULT dxgi_output_get_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *mode_desc) DECLSPEC_HIDDEN;
Please sort by the function name. We tend to keep declarations sorted in d3d code.
+HRESULT dxgi_output_set_display_mode(IDXGIOutput *iface, DXGI_MODE_DESC *target_mode_desc)
I'm not sure if "target_mode_desc" is necessarily better than "mode_desc" or simply "mode".
+{
- struct wined3d_display_mode wined3d_mode;
- struct dxgi_adapter *adapter;
- struct dxgi_output *target;
- struct wined3d *wined3d;
- HRESULT hr;
- target = impl_from_IDXGIOutput4((IDXGIOutput4 *)iface);
The cast from IDXGIOutput to IDXGIOutput4 isn't very nice. I am in favor of introducing unsafe_impl_from_IDXGIOuput(). See unsafe_impl_from_IDXGIAdapter().
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 4f01d9c..b060a30 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -501,11 +501,65 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeBuffers(IDXGISwapChain1 * return hr; }
+static HRESULT dxgi_resize_target(IDXGISwapChain1 *iface,
const DXGI_SWAP_CHAIN_DESC *desc, const DXGI_MODE_DESC *mode)
Personally, I'd name it "dxgi_swapchain_resize_target". It could also probably be moved to the top of the file, next to similar helpers (e.g. after dxgi_get_output_from_window()). Placing it between D3D11 swapchain methods isn't the best choice.