Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/d3d8/tests/device.c | 5 +--
dlls/d3d9/tests/device.c | 5 +--
dlls/dxgi/device.c | 16 +-------
dlls/dxgi/swapchain.c | 20 +---------
dlls/dxgi/tests/dxgi.c | 26 +------------
dlls/wined3d/directx.c | 69 ++++++++++++++++++++++++++--------
dlls/wined3d/wined3d_main.c | 4 +-
dlls/wined3d/wined3d_private.h | 2 -
8 files changed, 62 insertions(+), 85 deletions(-)
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index ffd940067e8..4eb1ab65e72 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -10455,9 +10455,8 @@ static void test_multi_adapter(void)
}
adapter_count = IDirect3D8_GetAdapterCount(d3d);
- todo_wine_if(expected_adapter_count > 1)
- ok(adapter_count == expected_adapter_count, "Got unexpected adapter count %u, expected %u.\n",
- adapter_count, expected_adapter_count);
+ ok(adapter_count == expected_adapter_count, "Got unexpected adapter count %u, expected %u.\n",
+ adapter_count, expected_adapter_count);
for (i = 0; i < adapter_count; ++i)
{
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index ef8d9a34e25..3ef9361886d 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -14149,9 +14149,8 @@ static void test_multi_adapter(void)
}
adapter_count = IDirect3D9_GetAdapterCount(d3d);
- todo_wine_if(expected_adapter_count > 1)
- ok(adapter_count == expected_adapter_count, "Got unexpected adapter count %u, expected %u.\n",
- adapter_count, expected_adapter_count);
+ ok(adapter_count == expected_adapter_count, "Got unexpected adapter count %u, expected %u.\n",
+ adapter_count, expected_adapter_count);
for (i = 0; i < adapter_count; ++i)
{
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index 5f0c40f2e47..74260f9b769 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -429,7 +429,6 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_factory_create_swapchain(IWineDX
struct wined3d_swapchain_desc wined3d_desc;
struct IDXGIOutput *containing_output;
struct d3d11_swapchain *object;
- struct IDXGIAdapter *adapter;
HRESULT hr;
TRACE("iface %p, factory %p, window %p, desc %p, fullscreen_desc %p, output %p, swapchain %p.\n",
@@ -438,20 +437,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_factory_create_swapchain(IWineDX
if (FAILED(hr = dxgi_get_output_from_window(factory, window, &containing_output)))
{
WARN("Failed to get output from window %p, hr %#x.\n", window, hr);
-
- /* FIXME: As wined3d only supports one output currently, even if a window is on a
- * non-primary output, the swapchain will use the primary output. Keep this behaviour
- * until all outputs are correctly enumerated. Otherwise it will create a regression
- * for applications that specify a device window on a non-primary output */
- if (FAILED(hr = IDXGIFactory_EnumAdapters(factory, 0, &adapter)))
- return hr;
-
- hr = IDXGIAdapter_EnumOutputs(adapter, 0, &containing_output);
- IDXGIAdapter_Release(adapter);
- if (FAILED(hr))
- return hr;
-
- FIXME("Using the primary output for the device window that is on a non-primary output.\n");
+ return hr;
}
hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, containing_output, window, desc,
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 0f335a71cb7..82e5fbf811d 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -3000,9 +3000,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
VkFenceCreateInfo fence_desc;
uint32_t queue_family_index;
VkSurfaceKHR vk_surface;
- IUnknown *device_parent;
VkInstance vk_instance;
- IDXGIAdapter *adapter;
IDXGIOutput *output;
VkBool32 supported;
VkDevice vk_device;
@@ -3043,27 +3041,11 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
return DXGI_ERROR_UNSUPPORTED;
}
- device_parent = vkd3d_get_device_parent(device);
- if (FAILED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter)))
- return hr;
-
if (FAILED(hr = dxgi_get_output_from_window((IDXGIFactory *)factory, window, &output)))
{
WARN("Failed to get output from window %p, hr %#x.\n", window, hr);
-
- /* FIXME: As wined3d only supports one output currently, even if a window is on a
- * non-primary output, the swapchain will use the primary output. Keep this behaviour
- * until all outputs are correctly enumerated. Otherwise it will create a regression
- * for applications that specify a device window on a non-primary output */
- if (FAILED(hr = IDXGIAdapter_EnumOutputs(adapter, 0, &output)))
- {
- IDXGIAdapter_Release(adapter);
- return hr;
- }
-
- FIXME("Using the primary output for the device window that is on a non-primary output.\n");
+ return hr;
}
- IDXGIAdapter_Release(adapter);
hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, output, window, swapchain_desc,
fullscreen_desc);
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index 53d768d1a36..2d8826fde8e 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -2178,22 +2178,6 @@ done:
DestroyWindow(creation_desc.OutputWindow);
}
-static HMONITOR get_primary_if_right_side_secondary(const DXGI_OUTPUT_DESC *output_desc)
-{
- HMONITOR primary, secondary;
- MONITORINFO mi;
- POINT pt = {0, 0};
-
- primary = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
- pt.x = output_desc->DesktopCoordinates.right;
- secondary = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
- mi.cbSize = sizeof(mi);
- if (secondary && secondary != primary
- && GetMonitorInfoW(primary, &mi) && (mi.dwFlags & MONITORINFOF_PRIMARY))
- return primary;
- return NULL;
-}
-
static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
{
unsigned int adapter_idx, output_idx, output_count;
@@ -2207,7 +2191,6 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
POINT points[4 * 16];
unsigned int i, j;
HMONITOR monitor;
- HMONITOR primary;
BOOL fullscreen;
ULONG refcount;
HRESULT hr;
@@ -2287,8 +2270,6 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
wine_dbgstr_rect(&output_desc.DesktopCoordinates),
wine_dbgstr_rect(&monitor_info.rcMonitor));
- primary = get_primary_if_right_side_secondary(&output_desc);
-
for (adapter_idx = 0; SUCCEEDED(IDXGIFactory_EnumAdapters(factory, adapter_idx, &adapter));
++adapter_idx)
{
@@ -2379,8 +2360,6 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
output_idx, i);
hr = IDXGISwapChain_GetContainingOutput(swapchain, &output2);
- /* Hack to prevent test failures with secondary on the right until multi-monitor support is improved. */
- todo_wine_if(primary && monitor != primary)
ok(hr == S_OK || broken(hr == DXGI_ERROR_UNSUPPORTED),
"Adapter %u output %u point %u: Failed to get containing output, hr %#x.\n",
adapter_idx, output_idx, i, hr);
@@ -5652,9 +5631,8 @@ done:
IDXGIFactory_Release(factory);
expected_output_count = GetSystemMetrics(SM_CMONITORS);
- todo_wine_if(expected_output_count > 1)
- ok(output_count == expected_output_count, "Expect output count %d, got %d\n",
- expected_output_count, output_count);
+ ok(output_count == expected_output_count, "Expect output count %d, got %d\n",
+ expected_output_count, output_count);
}
struct message
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 2764b113065..040a9f81083 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -140,6 +140,7 @@ static HRESULT wined3d_output_init(struct wined3d_output *output, unsigned int o
output->ordinal = ordinal;
lstrcpyW(output->device_name, device_name);
output->adapter = adapter;
+ output->screen_format = WINED3DFMT_UNKNOWN;
output->kmt_adapter = open_adapter_desc.hAdapter;
output->kmt_device = create_device_desc.hDevice;
output->vidpn_source_id = open_adapter_desc.VidPnSourceId;
@@ -3105,16 +3106,46 @@ static struct wined3d_adapter *wined3d_adapter_no3d_create(unsigned int ordinal,
return adapter;
}
+static BOOL wined3d_adapter_create_output(struct wined3d_adapter *adapter, const WCHAR *output_name)
+{
+ struct wined3d_output *outputs;
+ HRESULT hr;
+
+ if (!adapter->outputs && !(adapter->outputs = heap_calloc(1, sizeof(*adapter->outputs))))
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (!(outputs = heap_realloc(adapter->outputs,
+ sizeof(*adapter->outputs) * (adapter->output_count + 1))))
+ return FALSE;
+
+ adapter->outputs = outputs;
+ }
+
+ if (FAILED(hr = wined3d_output_init(&adapter->outputs[adapter->output_count],
+ adapter->output_count, adapter, output_name)))
+ {
+ ERR("Failed to initialise output %s, hr %#x.\n", wine_dbgstr_w(output_name), hr);
+ return FALSE;
+ }
+
+ ++adapter->output_count;
+ TRACE("Initialised output %s.\n", wine_dbgstr_w(output_name));
+ return TRUE;
+}
+
BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal, const LUID *luid,
const struct wined3d_adapter_ops *adapter_ops)
{
+ unsigned int output_idx = 0, primary_idx = 0;
DISPLAY_DEVICEW display_device;
- unsigned int output_idx;
BOOL ret = FALSE;
- HRESULT hr;
adapter->ordinal = ordinal;
adapter->output_count = 0;
+ adapter->outputs = NULL;
if (luid)
{
@@ -3132,23 +3163,29 @@ BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal,
TRACE("adapter %p LUID %08x:%08x.\n", adapter, adapter->luid.HighPart, adapter->luid.LowPart);
display_device.cb = sizeof(display_device);
- EnumDisplayDevicesW(NULL, ordinal, &display_device, 0);
- TRACE("Display device: %s.\n", debugstr_w(display_device.DeviceName));
- strcpyW(adapter->device_name, display_device.DeviceName);
-
- if (!(adapter->outputs = heap_calloc(1, sizeof(*adapter->outputs))))
+ while (EnumDisplayDevicesW(NULL, output_idx++, &display_device, 0))
{
- ERR("Failed to allocate outputs.\n");
- return FALSE;
- }
+ /* Detached outputs are not enumerated */
+ if (!(display_device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
+ continue;
- if (FAILED(hr = wined3d_output_init(&adapter->outputs[0], 0, adapter,
- display_device.DeviceName)))
- {
- ERR("Failed to initialise output, hr %#x.\n", hr);
- goto done;
+ if (display_device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
+ primary_idx = adapter->output_count;
+
+ if (!wined3d_adapter_create_output(adapter, display_device.DeviceName))
+ goto done;
+ }
+ TRACE("Initialised %d outputs for adapter %p.\n", adapter->output_count, adapter);
+
+ /* Make the primary output first */
+ if (primary_idx)
+ {
+ struct wined3d_output tmp = adapter->outputs[0];
+ adapter->outputs[0] = adapter->outputs[primary_idx];
+ adapter->outputs[0].ordinal = 0;
+ adapter->outputs[primary_idx] = tmp;
+ adapter->outputs[primary_idx].ordinal = primary_idx;
}
- adapter->output_count = 1;
memset(&adapter->driver_uuid, 0, sizeof(adapter->driver_uuid));
memset(&adapter->device_uuid, 0, sizeof(adapter->device_uuid));
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index 5ad390d9f56..293359714c3 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -497,9 +497,7 @@ static struct wined3d_output * wined3d_get_output_from_window(const struct wined
}
}
- /* Because wined3d only supports one output right now. A window can be on non-primary outputs
- * and thus fails to get its correct output. In this case, return the primary output for now */
- return &wined3d->adapters[0]->outputs[0];
+ return NULL;
}
static struct wined3d_wndproc *wined3d_find_wndproc(HWND window, struct wined3d *wined3d)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b3934f0d8e4..119ce3af033 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3368,8 +3368,6 @@ struct wined3d_adapter
GUID device_uuid;
LUID luid;
- WCHAR device_name[CCHDEVICENAME]; /* for use with e.g. ChangeDisplaySettings() */
-
void *formats;
size_t format_size;
--
2.27.0