[PATCH] dxgi: Implement dxgi_output_GetDesc().

Henri Verbeet hverbeet at codeweavers.com
Tue Nov 24 11:06:17 CST 2015


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 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




More information about the wine-patches mailing list