[PATCH 3/3] dxgi: Support Alt+Enter for d3d12 swapchains.
Zhiyi Zhang
zzhang at codeweavers.com
Tue Oct 6 08:30:59 CDT 2020
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/dxgi/swapchain.c | 51 ++++++++++++++++++++++++++++++++++++++----
dlls/dxgi/tests/dxgi.c | 16 ++++++-------
2 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index aa889bbe236..e74717056cb 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -1919,6 +1919,7 @@ static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain)
close_library(vulkan_module);
+ wined3d_swapchain_state_unregister(swapchain->state);
wined3d_swapchain_state_destroy(swapchain->state);
}
@@ -2289,18 +2290,37 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetFullscreenState(IDXGISwapCha
BOOL *fullscreen, IDXGIOutput **target)
{
struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain4(iface);
+ BOOL windowed;
+ HRESULT hr;
TRACE("iface %p, fullscreen %p, target %p.\n", iface, fullscreen, target);
- if (fullscreen)
+ if (fullscreen || target)
{
wined3d_mutex_lock();
- *fullscreen = !wined3d_swapchain_state_is_windowed(swapchain->state);
+ windowed = wined3d_swapchain_state_is_windowed(swapchain->state);
wined3d_mutex_unlock();
}
- if (target && (*target = swapchain->target))
- IDXGIOutput_AddRef(*target);
+ if (fullscreen)
+ *fullscreen = !windowed;
+
+ if (target)
+ {
+ if (!windowed)
+ {
+ if (!swapchain->target && FAILED(hr = IDXGISwapChain4_GetContainingOutput(iface,
+ &swapchain->target)))
+ return hr;
+
+ *target = swapchain->target;
+ IDXGIOutput_AddRef(*target);
+ }
+ else
+ {
+ *target = NULL;
+ }
+ }
return S_OK;
}
@@ -2936,6 +2956,24 @@ static BOOL init_vk_funcs(struct dxgi_vk_funcs *dxgi, VkInstance vk_instance, Vk
return TRUE;
}
+static void STDMETHODCALLTYPE d3d12_swapchain_windowed_state_changed(void *parent, BOOL windowed)
+{
+ struct d3d12_swapchain *swapchain = parent;
+
+ TRACE("parent %p, windowed %d.\n", parent, windowed);
+
+ if (windowed && swapchain->target)
+ {
+ IDXGIOutput_Release(swapchain->target);
+ swapchain->target = NULL;
+ }
+}
+
+static const struct wined3d_swapchain_state_parent_ops d3d12_swapchain_state_parent_ops =
+{
+ d3d12_swapchain_windowed_state_changed,
+};
+
static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGIFactory *factory,
ID3D12Device *device, ID3D12CommandQueue *queue, HWND window,
const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc)
@@ -2944,6 +2982,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
struct wined3d_swapchain_desc wined3d_desc;
VkWin32SurfaceCreateInfoKHR surface_desc;
VkPhysicalDevice vk_physical_device;
+ struct dxgi_factory *dxgi_factory;
VkFenceCreateInfo fence_desc;
uint32_t queue_family_index;
VkSurfaceKHR vk_surface;
@@ -3025,6 +3064,10 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
return hr;
}
+ dxgi_factory = unsafe_impl_from_IDXGIFactory((IDXGIFactory *)factory);
+ wined3d_swapchain_state_register(swapchain->state, dxgi_factory->wined3d, swapchain,
+ &d3d12_swapchain_state_parent_ops);
+
if (!fullscreen_desc->Windowed)
{
hr = wined3d_swapchain_state_set_fullscreen(swapchain->state, &wined3d_desc, NULL);
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index 5830426f756..c6ece51f2a8 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -2431,7 +2431,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
flush_events();
hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
ok(hr == S_OK, "GetFullscreenState failed, hr %#x.\n", hr);
- todo_wine_if(is_d3d12) ok(!fullscreen, "Expect swapchain not full screen.\n");
+ ok(!fullscreen, "Expect swapchain not full screen.\n");
/* Move the swapchain output window to the second output */
hr = IDXGIOutput_GetDesc(output2, &output_desc2);
@@ -2453,7 +2453,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
hr = IDXGIOutput_GetDesc(output2, &output_desc2);
ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
- todo_wine_if(is_d3d12) ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
+ ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
"Expect device name %s, got %s.\n", wine_dbgstr_w(output_desc2.DeviceName),
wine_dbgstr_w(output_desc.DeviceName));
IDXGIOutput_Release(output);
@@ -2465,7 +2465,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
hr = IDXGIOutput_GetDesc(output2, &output_desc2);
ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
- todo_wine_if(is_d3d12) ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
+ ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
"Expect device name %s, got %s.\n", wine_dbgstr_w(output_desc2.DeviceName),
wine_dbgstr_w(output_desc.DeviceName));
@@ -6148,7 +6148,6 @@ static void test_window_association(IUnknown *device, BOOL is_d3d12)
UINT flag;
BOOL expect_fullscreen;
BOOL broken_d3d10;
- BOOL todo_on_d3d12;
}
tests[] =
{
@@ -6162,15 +6161,15 @@ static void test_window_association(IUnknown *device, BOOL is_d3d12)
* - Posting them hangs the posting thread. Another thread that keeps
* sending input is needed to avoid the hang. The hang is not
* because of flush_events(). */
- {0, TRUE, FALSE, TRUE},
+ {0, TRUE},
{0, FALSE},
{DXGI_MWA_NO_WINDOW_CHANGES, FALSE},
{DXGI_MWA_NO_WINDOW_CHANGES, FALSE},
- {DXGI_MWA_NO_ALT_ENTER, FALSE, TRUE},
+ {DXGI_MWA_NO_ALT_ENTER},
{DXGI_MWA_NO_ALT_ENTER, FALSE},
- {DXGI_MWA_NO_PRINT_SCREEN, TRUE, FALSE, TRUE},
+ {DXGI_MWA_NO_PRINT_SCREEN, TRUE},
{DXGI_MWA_NO_PRINT_SCREEN, FALSE},
- {0, TRUE, FALSE, TRUE},
+ {0, TRUE},
{0, FALSE}
};
@@ -6272,7 +6271,6 @@ static void test_window_association(IUnknown *device, BOOL is_d3d12)
output = NULL;
hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, &output);
ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
- todo_wine_if(is_d3d12 && tests[i].todo_on_d3d12)
ok(fullscreen == tests[i].expect_fullscreen
|| broken(tests[i].broken_d3d10 && fullscreen),
"Test %u: Got unexpected fullscreen %#x.\n", i, fullscreen);
--
2.25.1
More information about the wine-devel
mailing list