From: Henri Verbeet Subject: [PATCH] dxgi: Implement dxgi_output_GetDesc(). Message-Id: <1448384777-15162-1-git-send-email-hverbeet@codeweavers.com> Date: Tue, 24 Nov 2015 18:06:17 +0100 Signed-off-by: Henri Verbeet --- dlls/d3d8/directx.c | 13 +++++++--- dlls/d3d9/directx.c | 13 +++++++--- dlls/ddraw/main.c | 6 +++-- dlls/dxgi/output.c | 28 +++++++++++++++++++-- dlls/dxgi/tests/device.c | 56 ++++++++++++++++++++++++++++++++++++++++++ dlls/wined3d/directx.c | 35 ++++++++++++++++++++------ dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 2 +- include/wine/wined3d.h | 12 ++++++++- 9 files changed, 146 insertions(+), 21 deletions(-) diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 132a56f..12fdc02 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -338,15 +338,22 @@ static HRESULT WINAPI d3d8_GetDeviceCaps(IDirect3D8 *iface, UINT adapter, D3DDEV static HMONITOR WINAPI d3d8_GetAdapterMonitor(IDirect3D8 *iface, UINT adapter) { struct d3d8 *d3d8 = impl_from_IDirect3D8(iface); - HMONITOR ret; + struct wined3d_output_desc desc; + HRESULT hr; TRACE("iface %p, adapter %u.\n", iface, adapter); wined3d_mutex_lock(); - ret = wined3d_get_adapter_monitor(d3d8->wined3d, adapter); + hr = wined3d_get_output_desc(d3d8->wined3d, adapter, &desc); wined3d_mutex_unlock(); - return ret; + if (FAILED(hr)) + { + WARN("Failed to get output desc, hr %#x.\n", hr); + return NULL; + } + + return desc.monitor; } static HRESULT WINAPI d3d8_CreateDevice(IDirect3D8 *iface, UINT adapter, diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index 58c4d44..fb18345 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -436,15 +436,22 @@ static HRESULT WINAPI d3d9_GetDeviceCaps(IDirect3D9Ex *iface, UINT adapter, D3DD static HMONITOR WINAPI d3d9_GetAdapterMonitor(IDirect3D9Ex *iface, UINT adapter) { struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface); - HMONITOR ret; + struct wined3d_output_desc desc; + HRESULT hr; TRACE("iface %p, adapter %u.\n", iface, adapter); wined3d_mutex_lock(); - ret = wined3d_get_adapter_monitor(d3d9->wined3d, adapter); + hr = wined3d_get_output_desc(d3d9->wined3d, adapter, &desc); wined3d_mutex_unlock(); - return ret; + if (FAILED(hr)) + { + WARN("Failed to get output desc, hr %#x.\n", hr); + return NULL; + } + + return desc.monitor; } static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_CreateDevice(IDirect3D9Ex *iface, UINT adapter, diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index 06b448f..0f7398b 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -60,6 +60,7 @@ static void ddraw_enumerate_secondary_devices(struct wined3d *wined3d, LPDDENUMC void *context) { struct wined3d_adapter_identifier adapter_id; + struct wined3d_output_desc output_desc; BOOL cont_enum = TRUE; HRESULT hr = S_OK; UINT adapter = 0; @@ -76,13 +77,14 @@ static void ddraw_enumerate_secondary_devices(struct wined3d *wined3d, LPDDENUMC adapter_id.description = DriverDescription; adapter_id.description_size = sizeof(DriverDescription); wined3d_mutex_lock(); - hr = wined3d_get_adapter_identifier(wined3d, adapter, 0x0, &adapter_id); + if (SUCCEEDED(hr = wined3d_get_adapter_identifier(wined3d, adapter, 0x0, &adapter_id))) + hr = wined3d_get_output_desc(wined3d, adapter, &output_desc); wined3d_mutex_unlock(); if (SUCCEEDED(hr)) { TRACE("Interface %d: %s\n", adapter, wine_dbgstr_guid(&adapter_id.device_identifier)); cont_enum = callback(&adapter_id.device_identifier, adapter_id.description, - adapter_id.device_name, context, wined3d_get_adapter_monitor(wined3d, adapter)); + adapter_id.device_name, context, output_desc.monitor); } } } diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index 198f120..65e60aa 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -121,9 +121,33 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetParent(IDXGIOutput *iface, static HRESULT STDMETHODCALLTYPE dxgi_output_GetDesc(IDXGIOutput *iface, DXGI_OUTPUT_DESC *desc) { - FIXME("iface %p, desc %p stub!\n", iface, desc); + struct dxgi_output *output = impl_from_IDXGIOutput(iface); + struct wined3d_output_desc wined3d_desc; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) + return E_INVALIDARG; + + wined3d_mutex_lock(); + hr = wined3d_get_output_desc(output->adapter->parent->wined3d, + output->adapter->ordinal, &wined3d_desc); + wined3d_mutex_unlock(); + + if (FAILED(hr)) + { + WARN("Failed to get output desc, hr %#x.\n", hr); + return hr; + } + + memcpy(desc->DeviceName, wined3d_desc.device_name, sizeof(desc->DeviceName)); + desc->DesktopCoordinates = wined3d_desc.desktop_rect; + desc->AttachedToDesktop = wined3d_desc.attached_to_desktop; + desc->Rotation = wined3d_desc.rotation; + desc->Monitor = wined3d_desc.monitor; + + return S_OK; } static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput *iface, diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index 8a4b3f3..f5480de 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -1271,6 +1271,61 @@ static void test_maximum_frame_latency(void) ok(!refcount, "Device has %u references left.\n", refcount); } +static void test_output_desc(void) +{ + DXGI_OUTPUT_DESC desc; + IDXGIFactory *factory; + IDXGIAdapter *adapter; + IDXGIOutput *output; + unsigned int i, j; + HRESULT hr; + + hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create DXGI factory, hr %#x.\n", hr); + + for (i = 0; ; ++i) + { + hr = IDXGIFactory_EnumAdapters(factory, i, &adapter); + if (hr == DXGI_ERROR_NOT_FOUND) + break; + ok(SUCCEEDED(hr), "Failed to enumerate adapter %u, hr %#x.\n", i, hr); + + for (j = 0; ; ++j) + { + MONITORINFOEXW monitor_info; + BOOL ret; + + hr = IDXGIAdapter_EnumOutputs(adapter, j, &output); + if (hr == DXGI_ERROR_NOT_FOUND) + break; + ok(SUCCEEDED(hr), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j, i, hr); + + hr = IDXGIOutput_GetDesc(output, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x for output %u on adapter %u.\n", hr, j, i); + hr = IDXGIOutput_GetDesc(output, &desc); + ok(SUCCEEDED(hr), "Failed to get desc for output %u on adapter %u, hr %#x.\n", j, i, hr); + + monitor_info.cbSize = sizeof(monitor_info); + ret = GetMonitorInfoW(desc.Monitor, (MONITORINFO *)&monitor_info); + ok(ret, "Failed to get monitor info.\n"); + ok(!lstrcmpW(desc.DeviceName, monitor_info.szDevice), "Got unexpected device name %s, expected %s.\n", + wine_dbgstr_w(desc.DeviceName), wine_dbgstr_w(monitor_info.szDevice)); + ok(!memcmp(&desc.DesktopCoordinates, &monitor_info.rcMonitor, sizeof(desc.DesktopCoordinates)), + "Got unexpected desktop coordinates {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n", + desc.DesktopCoordinates.left, desc.DesktopCoordinates.top, + desc.DesktopCoordinates.right, desc.DesktopCoordinates.bottom, + monitor_info.rcMonitor.left, monitor_info.rcMonitor.top, + monitor_info.rcMonitor.right, monitor_info.rcMonitor.bottom); + + IDXGIOutput_Release(output); + } + + IDXGIAdapter_Release(adapter); + } + + IDXGIFactory_Release(factory); +} + START_TEST(device) { pCreateDXGIFactory1 = (void *)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1"); @@ -1289,4 +1344,5 @@ START_TEST(device) test_swapchain_resize(); test_swapchain_parameters(); test_maximum_frame_latency(); + test_output_desc(); } diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 1a7d837..6aae3a3 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3851,14 +3851,37 @@ HRESULT CDECL wined3d_register_software_device(struct wined3d *wined3d, void *in return WINED3D_OK; } -HMONITOR CDECL wined3d_get_adapter_monitor(const struct wined3d *wined3d, UINT adapter_idx) +HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx, + struct wined3d_output_desc *desc) { - TRACE("wined3d %p, adapter_idx %u.\n", wined3d, adapter_idx); + enum wined3d_display_rotation rotation; + const struct wined3d_adapter *adapter; + struct wined3d_display_mode mode; + HMONITOR monitor; + HRESULT hr; + + TRACE("wined3d %p, adapter_idx %u, desc %p.\n", wined3d, adapter_idx, desc); if (adapter_idx >= wined3d->adapter_count) - return NULL; + return WINED3DERR_INVALIDCALL; + + adapter = &wined3d->adapters[adapter_idx]; + if (!(monitor = MonitorFromPoint(adapter->monitor_position, MONITOR_DEFAULTTOPRIMARY))) + return WINED3DERR_INVALIDCALL; + + if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &mode, &rotation))) + return hr; + + memcpy(desc->device_name, adapter->DeviceName, sizeof(desc->device_name)); + SetRect(&desc->desktop_rect, 0, 0, mode.width, mode.height); + OffsetRect(&desc->desktop_rect, adapter->monitor_position.x, adapter->monitor_position.y); + /* FIXME: We should get this from EnumDisplayDevices() when the adapters + * are created. */ + desc->attached_to_desktop = TRUE; + desc->rotation = rotation; + desc->monitor = monitor; - return MonitorFromPoint(wined3d->adapters[adapter_idx].monitorPoint, MONITOR_DEFAULTTOPRIMARY); + return WINED3D_OK; } /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes @@ -5813,8 +5836,6 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) TRACE("adapter %p, ordinal %u.\n", adapter, ordinal); adapter->ordinal = ordinal; - adapter->monitorPoint.x = -1; - adapter->monitorPoint.y = -1; /* Dynamically load all GL core functions */ #ifdef USE_WIN32_OPENGL @@ -5929,8 +5950,6 @@ static void wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordi memset(adapter, 0, sizeof(*adapter)); adapter->ordinal = ordinal; - adapter->monitorPoint.x = -1; - adapter->monitorPoint.y = -1; adapter->driver_info.name = "Display"; adapter->driver_info.description = "WineD3D DirectDraw Emulation"; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index a7e625d..d70a0c4 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -14,9 +14,9 @@ @ cdecl wined3d_get_adapter_display_mode(ptr long ptr ptr) @ cdecl wined3d_get_adapter_identifier(ptr long long ptr) @ cdecl wined3d_get_adapter_mode_count(ptr long long long) -@ cdecl wined3d_get_adapter_monitor(ptr long) @ cdecl wined3d_get_adapter_raster_status(ptr long ptr) @ cdecl wined3d_get_device_caps(ptr long long ptr) +@ cdecl wined3d_get_output_desc(ptr long ptr) @ cdecl wined3d_incref(ptr) @ cdecl wined3d_register_software_device(ptr ptr) @ cdecl wined3d_set_adapter_display_mode(ptr long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index a60919e..6819330 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1799,7 +1799,7 @@ struct wined3d_d3d_info struct wined3d_adapter { UINT ordinal; - POINT monitorPoint; + POINT monitor_position; enum wined3d_format_id screen_format; struct wined3d_gl_info gl_info; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 2deb450..8b29aba 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1998,6 +1998,15 @@ struct wined3d_shader_desc unsigned int max_version; }; +struct wined3d_output_desc +{ + WCHAR device_name[CCHDEVICENAME]; + RECT desktop_rect; + BOOL attached_to_desktop; + enum wined3d_display_rotation rotation; + HMONITOR monitor; +}; + struct wined3d_parent_ops { void (__stdcall *wined3d_object_destroyed)(void *parent); @@ -2094,11 +2103,12 @@ HRESULT __cdecl wined3d_get_adapter_identifier(const struct wined3d *wined3d, UI DWORD flags, struct wined3d_adapter_identifier *identifier); UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering); -HMONITOR __cdecl wined3d_get_adapter_monitor(const struct wined3d *wined3d, UINT adapter_idx); HRESULT __cdecl wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx, struct wined3d_raster_status *raster_status); HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, WINED3DCAPS *caps); +HRESULT __cdecl wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx, + struct wined3d_output_desc *desc); ULONG __cdecl wined3d_incref(struct wined3d *wined3d); HRESULT __cdecl wined3d_register_software_device(struct wined3d *wined3d, void *init_function); HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d, -- 2.1.4