---
Note that this code never runs in d3d10+ for a 0 pixelformat. Dxgi/tests/dxgi.c:2032 has a test that shows it results in an error.
From: Stefan Dösinger stefan@codeweavers.com
---
Note that this code never runs in d3d10+ for a 0 pixelformat. Dxgi/tests/dxgi.c:2032 has a test that shows it results in an error. --- dlls/wined3d/swapchain.c | 53 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index f8179e2a70d..cc740e657e1 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1400,7 +1400,31 @@ static HRESULT wined3d_swapchain_state_init(struct wined3d_swapchain_state *stat return hr; }
- if (!desc->windowed) + if (state->desc.windowed) + { + RECT client_rect; + + GetClientRect(window, &client_rect); + TRACE("Client rect %s.\n", wine_dbgstr_rect(&client_rect)); + + if (!state->desc.backbuffer_width) + { + state->desc.backbuffer_width = client_rect.right ? client_rect.right : 8; + TRACE("Updating width to %u.\n", state->desc.backbuffer_width); + } + if (!state->desc.backbuffer_height) + { + state->desc.backbuffer_height = client_rect.bottom ? client_rect.bottom : 8; + TRACE("Updating height to %u.\n", state->desc.backbuffer_height); + } + + if (state->desc.backbuffer_format == WINED3DFMT_UNKNOWN) + { + state->desc.backbuffer_format = state->original_mode.format_id; + TRACE("Updating format to %s.\n", debug_d3dformat(state->original_mode.format_id)); + } + } + else { if (desc->flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) { @@ -1486,7 +1510,6 @@ static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struc struct wined3d_output_desc output_desc; BOOL displaymode_set = FALSE; HRESULT hr = E_FAIL; - RECT client_rect; unsigned int i; HWND window;
@@ -1526,29 +1549,7 @@ static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struc swapchain->swap_interval = WINED3D_SWAP_INTERVAL_DEFAULT; swapchain_set_max_frame_latency(swapchain, device);
- GetClientRect(window, &client_rect); - if (desc->windowed) - { - TRACE("Client rect %s.\n", wine_dbgstr_rect(&client_rect)); - - if (!desc->backbuffer_width) - { - desc->backbuffer_width = client_rect.right ? client_rect.right : 8; - TRACE("Updating width to %u.\n", desc->backbuffer_width); - } - if (!desc->backbuffer_height) - { - desc->backbuffer_height = client_rect.bottom ? client_rect.bottom : 8; - TRACE("Updating height to %u.\n", desc->backbuffer_height); - } - - if (desc->backbuffer_format == WINED3DFMT_UNKNOWN) - { - desc->backbuffer_format = swapchain->state.original_mode.format_id; - TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->state.original_mode.format_id)); - } - } - else + if (!desc->windowed) { if (FAILED(hr = wined3d_output_get_desc(desc->output, &output_desc))) { @@ -1560,7 +1561,7 @@ static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struc output_desc.desktop_rect.left, output_desc.desktop_rect.top, desc->backbuffer_width, desc->backbuffer_height); } - swapchain->state.desc = *desc; + wined3d_swapchain_apply_sample_count_override(swapchain, swapchain->state.desc.backbuffer_format, &swapchain->state.desc.multisample_type, &swapchain->state.desc.multisample_quality);
From: Stefan Dösinger stefan@codeweavers.com
--- dlls/dxgi/swapchain.c | 2 ++ dlls/wined3d/swapchain.c | 9 +++++++++ dlls/wined3d/wined3d.spec | 1 + include/wine/wined3d.h | 2 ++ 4 files changed, 14 insertions(+)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index d567056062e..083808dd238 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -3130,6 +3130,8 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI return hr; }
+ wined3d_swapchain_state_get_size(swapchain->state, &swapchain->desc.Width, &swapchain->desc.Height); + if (fullscreen) { wined3d_desc.windowed = FALSE; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index cc740e657e1..36116c0ede9 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -2428,6 +2428,15 @@ BOOL CDECL wined3d_swapchain_state_is_windowed(const struct wined3d_swapchain_st return state->desc.windowed; }
+void CDECL wined3d_swapchain_state_get_size(const struct wined3d_swapchain_state *state, + unsigned int *width, unsigned int *height) +{ + TRACE("state %p.\n", state); + + *width = state->desc.backbuffer_width; + *height = state->desc.backbuffer_height; +} + void CDECL wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state) { wined3d_swapchain_state_cleanup(state); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 39a0dd3a299..3094fac6f3c 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -292,6 +292,7 @@
@ cdecl wined3d_swapchain_state_create(ptr ptr ptr ptr ptr) @ cdecl wined3d_swapchain_state_destroy(ptr) +@ cdecl wined3d_swapchain_state_get_size(ptr ptr ptr) @ cdecl wined3d_swapchain_state_is_windowed(ptr) @ cdecl wined3d_swapchain_state_resize_target(ptr ptr) @ cdecl wined3d_swapchain_state_set_fullscreen(ptr ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 2317dc17078..230eb1a8744 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2854,6 +2854,8 @@ HRESULT __cdecl wined3d_swapchain_state_create(const struct wined3d_swapchain_de HWND window, struct wined3d *wined3d, struct wined3d_swapchain_state_parent *state_parent, struct wined3d_swapchain_state **state); void __cdecl wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state); +void __cdecl wined3d_swapchain_state_get_size(const struct wined3d_swapchain_state *state, + unsigned int *width, unsigned int *height); BOOL __cdecl wined3d_swapchain_state_is_windowed(const struct wined3d_swapchain_state *state); HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state, const struct wined3d_display_mode *mode);
From: Stefan Dösinger stefan@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 71 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 91e78c5a56c..85e8d4984fa 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -7886,6 +7886,75 @@ done: ok(!refcount, "Device has %lu references left.\n", refcount); }
+static void test_zero_size(IUnknown *device, BOOL is_d3d12) +{ + DXGI_SWAP_CHAIN_DESC swapchain_desc; + IDXGISwapChain *swapchain; + unsigned int i, expected; + IDXGIFactory *factory; + HWND window; + HRESULT hr; + RECT r; + + static const struct + { + INT w, h; + } + tests[] = + { + {0, 0}, + {200, 0}, + {0, 200}, + {200, 200}, + /* FIXME: How to create a window with a client rect width or height above 0 but less than 8? + * If I try to AdjustWindowRect a (100,100)-(104,104) rectangle I get a larger window. I + * suspect the decoration style and DPI will play into it too. The size below creates a + * 176x4 client rect on my system. */ + {100, 60} + }; + + get_factory(device, is_d3d12, &factory); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + window = CreateWindowA("static", "dxgi_test", WS_VISIBLE, 0, 0, tests[i].w, tests[i].h, 0, 0, 0, 0); + swapchain_desc.BufferDesc.Width = 0; + swapchain_desc.BufferDesc.Height = 0; + swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; + swapchain_desc.BufferDesc.RefreshRate.Denominator = 60; + swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = is_d3d12 ? 2 : 1; + swapchain_desc.OutputWindow = window; + swapchain_desc.Windowed = TRUE; + swapchain_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.Flags = 0; + + hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!swapchain_desc.BufferDesc.Width && !swapchain_desc.BufferDesc.Height, "Input desc was modified.\n"); + + hr = IDXGISwapChain_GetDesc(swapchain, &swapchain_desc); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + GetClientRect(swapchain_desc.OutputWindow, &r); + expected = r.right > 0 ? r.right : 8; + ok(swapchain_desc.BufferDesc.Width == expected, "Got width %u, expected %u, test %u.\n", + swapchain_desc.BufferDesc.Width, expected, i); + expected = r.bottom > 0 ? r.bottom : 8; + ok(swapchain_desc.BufferDesc.Height == expected, "Got height %u, expected %u, test %u.\n", + swapchain_desc.BufferDesc.Height, expected, i); + + IDXGISwapChain_Release(swapchain); + DestroyWindow(window); + } + + IDXGIFactory_Release(factory); +} + static void run_on_d3d10(void (*test_func)(IUnknown *device, BOOL is_d3d12)) { IDXGIDevice *device; @@ -8010,6 +8079,7 @@ START_TEST(dxgi) run_on_d3d10(test_swapchain_present_count); run_on_d3d10(test_resize_target_wndproc); run_on_d3d10(test_swapchain_window_messages); + run_on_d3d10(test_zero_size);
if (!(d3d12_module = LoadLibraryA("d3d12.dll"))) { @@ -8043,6 +8113,7 @@ START_TEST(dxgi) run_on_d3d12(test_swapchain_present_count); run_on_d3d12(test_resize_target_wndproc); run_on_d3d12(test_swapchain_window_messages); + run_on_d3d12(test_zero_size);
FreeLibrary(d3d12_module); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=135810
Your paranoid android.
=== debian11 (32 bit report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
=== debian11 (32 bit ar:MA report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
=== debian11 (32 bit de report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
=== debian11 (32 bit fr report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
=== debian11 (32 bit he:IL report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
=== debian11 (32 bit hi:IN report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
=== debian11 (32 bit ja:JP report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
=== debian11 (32 bit zh:CN report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
=== debian11b (32 bit WoW report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(640,480).
=== debian11b (64 bit WoW report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,768), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,768), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,768), expected (0,0)-(640,480).
=== debian11 (32 bit report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
This failure is in a different test, but it also hasn't happened before. Could you please take a look at it?
On Thu Aug 10 13:41:12 2023 +0000, Zebediah Figura wrote:
=== debian11 (32 bit report) ===
dxgi: dxgi.c:2192: Test failed: Got window rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got client rect (0,0)-(1024,737), expected (0,0)-(640,480). dxgi.c:2192: Test failed: Got monitor rect (0,0)-(1024,737), expected (0,0)-(640,480).
This failure is in a different test, but it also hasn't happened before. Could you please take a look at it?
I get a similar-looking (but different, High DPI related) failure on Windows so I mentally blocked this.
But oof. The issue here is that fullscreen swapchains take the current mode size whereas windowed swapchains the current window size. So far so good. But dxgi creates FS swapchains as windowed and then switches them to fullscreen. But by the time we switch to FS the swapchain's desc now has a non-zero size
On Thu Aug 10 13:41:11 2023 +0000, Stefan Dösinger wrote:
I get a similar-looking (but different, High DPI related) failure on Windows so I mentally blocked this. But oof. The issue here is that fullscreen swapchains take the current mode size whereas windowed swapchains the current window size. So far so good. But dxgi creates FS swapchains as windowed and then switches them to fullscreen. But by the time we switch to FS the swapchain's desc now has a non-zero size
Actually, it is the other way around. The selected mode depends on the window size and currently dxgi depends on us feeding the window size back into the input description, which is not const. With my patch the input is unmodified, so we end up choosing the current desktop mode.