From: Rémi Bernon <rbernon(a)codeweavers.com> The client rect might be empty or invalid. Fallout 3 in particular does a bogus call sequence after restoring minimized window which causes the window and client rects to be empty: SetRect(&rect, 0, 0, width, height); AdjustWindowRectEx(&rect, style, FALSE, 0); SetWindowPos(hwnd, 0, rect.left, rect.bottom, rect.right - rect.left, rect.top - rect.bottom, 0); We either need to hook the window messages and inhibit such window size changes, or we need to avoid relying on client and window rect when in fullscreen mode. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58844 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58443 --- dlls/wined3d/context_gl.c | 18 ++++++++++++++++++ dlls/wined3d/swapchain.c | 29 +++++++++++++++++++++++++++-- dlls/wined3d/texture.c | 15 +++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index ac1b9370fc1..223652a51cc 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -2393,6 +2393,24 @@ static void wined3d_context_gl_get_rt_size(const struct wined3d_context_gl *cont { RECT window_size; + if (!rt->swapchain->state.desc.windowed) + { + struct wined3d_display_mode actual_mode; + struct wined3d_output *output; + HRESULT hr; + + if (!(output = wined3d_swapchain_get_output(rt->swapchain))) + ERR("Failed to get swapchain output.\n"); + else if (FAILED(hr = wined3d_output_get_display_mode(output, &actual_mode, NULL))) + ERR("Failed to get display mode, hr %#lx.\n", hr); + else + { + size->cx = actual_mode.width; + size->cy = actual_mode.height; + return; + } + } + GetClientRect(context_gl->window, &window_size); size->cx = window_size.right - window_size.left; size->cy = window_size.bottom - window_size.top; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index f19f51d0e51..26aea32759d 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -40,6 +40,31 @@ static BOOL set_window_present_rect(HWND hwnd, UINT x, UINT y, UINT width, UINT return !D3DKMTEscape(&escape); } +static void get_swapchain_present_rect(struct wined3d_swapchain *swapchain, RECT *rect) +{ + if (!swapchain->state.desc.windowed) + { + struct wined3d_display_mode actual_mode; + struct wined3d_output_desc output_desc; + struct wined3d_output *output; + HRESULT hr; + + if (!(output = wined3d_swapchain_get_output(swapchain))) + ERR("Failed to get swapchain output.\n"); + else if (FAILED(hr = wined3d_output_get_desc(output, &output_desc))) + ERR("Failed to get output description, hr %#lx.\n", hr); + else if (FAILED(hr = wined3d_output_get_display_mode(output, &actual_mode, NULL))) + ERR("Failed to get display mode, hr %#lx.\n", hr); + else + SetRect(rect, output_desc.desktop_rect.left, output_desc.desktop_rect.top, + output_desc.desktop_rect.left + actual_mode.width, + output_desc.desktop_rect.top + actual_mode.height); + return; + } + + GetClientRect(swapchain->win_handle, rect); +} + void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) { HRESULT hr; @@ -233,7 +258,7 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain, if (!dst_rect) { - GetClientRect(swapchain->win_handle, &d); + get_swapchain_present_rect(swapchain, &d); dst_rect = &d; } @@ -581,7 +606,7 @@ static bool swapchain_present_is_partial_copy(struct wined3d_swapchain *swapchai if (swap_effect != WINED3D_SWAP_EFFECT_COPY && swap_effect != WINED3D_SWAP_EFFECT_COPY_VSYNC) return false; - GetClientRect(swapchain->win_handle, &client_rect); + get_swapchain_present_rect(swapchain, &client_rect); t = client_rect.right - client_rect.left; if ((dst_rect->left && dst_rect->right) || abs(dst_rect->right - dst_rect->left) != t) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index dd61a2f0d3c..0d2ccea4541 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -82,6 +82,21 @@ void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *tex } GetClientRect(window, &windowsize); + + if (!texture->swapchain->state.desc.windowed) + { + struct wined3d_display_mode actual_mode; + struct wined3d_output *output; + HRESULT hr; + + if (!(output = wined3d_swapchain_get_output(texture->swapchain))) + ERR("Failed to get swapchain output.\n"); + else if (FAILED(hr = wined3d_output_get_display_mode(output, &actual_mode, NULL))) + ERR("Failed to get display mode, hr %#lx.\n", hr); + else + SetRect(&windowsize, 0, 0, actual_mode.width, actual_mode.height); + } + drawable_height = windowsize.bottom - windowsize.top; rect->top = drawable_height - rect->top; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9585