Signed-off-by: Zhiyi Zhang zzhang@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;