[PATCH 3/5] wined3d: Introduce wined3d_adapter_enum_outputs().

Zhiyi Zhang zzhang at codeweavers.com
Mon Mar 2 02:23:57 CST 2020


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/ddraw/main.c              | 41 ++++++++++++++++++++++++++-------
 dlls/dxgi/adapter.c            |  2 +-
 dlls/dxgi/dxgi_private.h       |  4 +++-
 dlls/dxgi/output.c             | 21 ++++++++---------
 dlls/wined3d/directx.c         | 42 ++++++++++++++++++++++------------
 dlls/wined3d/wined3d.spec      |  2 +-
 dlls/wined3d/wined3d_private.h |  2 +-
 include/wine/wined3d.h         |  3 ++-
 8 files changed, 78 insertions(+), 39 deletions(-)

diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
index 5236b39b643..263a1e46c67 100644
--- a/dlls/ddraw/main.c
+++ b/dlls/ddraw/main.c
@@ -57,12 +57,15 @@ static void ddraw_enumerate_secondary_devices(struct wined3d *wined3d, LPDDENUMC
                                               void *context)
 {
     struct wined3d_adapter_identifier adapter_id;
+    struct wined3d_adapter *wined3d_adapter;
     struct wined3d_output_desc output_desc;
+    struct wined3d_output *wined3d_output;
+    UINT adapter_idx = 0, output_idx;
+    UINT interface_count = 0;
     BOOL cont_enum = TRUE;
-    HRESULT hr = S_OK;
-    UINT adapter = 0;
+    HRESULT hr;
 
-    for (adapter = 0; SUCCEEDED(hr) && cont_enum; adapter++)
+    while (cont_enum && SUCCEEDED(wined3d_enum_adapters(wined3d, adapter_idx, &wined3d_adapter)))
     {
         char DriverName[512] = "", DriverDescription[512] = "";
 
@@ -73,16 +76,38 @@ static void ddraw_enumerate_secondary_devices(struct wined3d *wined3d, LPDDENUMC
         adapter_id.device_name_size = sizeof(DriverName);
         adapter_id.description = DriverDescription;
         adapter_id.description_size = sizeof(DriverDescription);
+
         wined3d_mutex_lock();
-        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))
+        if (FAILED(hr = wined3d_get_adapter_identifier(wined3d, adapter_idx, 0x0, &adapter_id)))
         {
-            TRACE("Interface %d: %s\n", adapter, wine_dbgstr_guid(&adapter_id.device_identifier));
+            WARN("Failed to get adapter identifier, hr %#x.\n", hr);
+            wined3d_mutex_unlock();
+            break;
+        }
+        wined3d_mutex_unlock();
+
+        for (output_idx = 0; cont_enum && SUCCEEDED(wined3d_adapter_enum_outputs(wined3d_adapter,
+                output_idx, &wined3d_output)); ++output_idx)
+        {
+            wined3d_mutex_lock();
+            if (FAILED(hr = wined3d_get_output_desc(wined3d, output_idx, &output_desc)))
+            {
+                WARN("Failed to get output description, hr %#x.\n", hr);
+                wined3d_mutex_unlock();
+                break;
+            }
+            wined3d_mutex_unlock();
+
+            TRACE("Interface %u: %s\n", interface_count++,
+                    wine_dbgstr_guid(&adapter_id.device_identifier));
             cont_enum = callback(&adapter_id.device_identifier, adapter_id.description,
                     adapter_id.device_name, context, output_desc.monitor);
         }
+
+        if (FAILED(hr))
+            break;
+
+        ++adapter_idx;
     }
 }
 
diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c
index 590f9f13cc3..77516015add 100644
--- a/dlls/dxgi/adapter.c
+++ b/dlls/dxgi/adapter.c
@@ -139,7 +139,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_EnumOutputs(IWineDXGIAdapter *ifac
         return DXGI_ERROR_NOT_FOUND;
     }
 
-    if (FAILED(hr = dxgi_output_create(adapter, &output_object)))
+    if (FAILED(hr = dxgi_output_create(adapter, output_idx, &output_object)))
     {
         *output = NULL;
         return hr;
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index 56939e2aaa6..99fdcf62d43 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -144,11 +144,13 @@ struct dxgi_output
 {
     IDXGIOutput4 IDXGIOutput4_iface;
     LONG refcount;
+    struct wined3d_output *wined3d_output;
     struct wined3d_private_store private_store;
     struct dxgi_adapter *adapter;
 };
 
-HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output) DECLSPEC_HIDDEN;
+HRESULT dxgi_output_create(struct dxgi_adapter *adapter, UINT output_idx,
+        struct dxgi_output **output) DECLSPEC_HIDDEN;
 struct dxgi_output *unsafe_impl_from_IDXGIOutput(IDXGIOutput *iface) DECLSPEC_HIDDEN;
 
 /* IDXGIAdapter */
diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c
index a2331358e69..122f6366b0c 100644
--- a/dlls/dxgi/output.c
+++ b/dlls/dxgi/output.c
@@ -365,8 +365,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_WaitForVBlank(IDXGIOutput4 *iface)
 static HRESULT STDMETHODCALLTYPE dxgi_output_TakeOwnership(IDXGIOutput4 *iface, IUnknown *device, BOOL exclusive)
 {
     struct dxgi_output *output = impl_from_IDXGIOutput4(iface);
-    struct wined3d_output *wined3d_output;
-    HRESULT hr = DXGI_ERROR_INVALID_CALL;
+    HRESULT hr;
 
     TRACE("iface %p, device %p, exclusive %d.\n", iface, device, exclusive);
 
@@ -374,9 +373,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_TakeOwnership(IDXGIOutput4 *iface,
         return DXGI_ERROR_INVALID_CALL;
 
     wined3d_mutex_lock();
-    if ((wined3d_output = wined3d_get_adapter_output(output->adapter->factory->wined3d,
-            output->adapter->ordinal)))
-        hr = wined3d_output_take_ownership(wined3d_output, exclusive);
+    hr = wined3d_output_take_ownership(output->wined3d_output, exclusive);
     wined3d_mutex_unlock();
 
     return hr;
@@ -385,14 +382,11 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_TakeOwnership(IDXGIOutput4 *iface,
 static void STDMETHODCALLTYPE dxgi_output_ReleaseOwnership(IDXGIOutput4 *iface)
 {
     struct dxgi_output *output = impl_from_IDXGIOutput4(iface);
-    struct wined3d_output *wined3d_output;
 
     TRACE("iface %p.\n", iface);
 
     wined3d_mutex_lock();
-    if ((wined3d_output = wined3d_get_adapter_output(output->adapter->factory->wined3d,
-            output->adapter->ordinal)))
-        wined3d_output_release_ownership(wined3d_output);
+    wined3d_output_release_ownership(output->wined3d_output);
     wined3d_mutex_unlock();
 }
 
@@ -581,20 +575,23 @@ struct dxgi_output *unsafe_impl_from_IDXGIOutput(IDXGIOutput *iface)
     return CONTAINING_RECORD(iface, struct dxgi_output, IDXGIOutput4_iface);
 }
 
-static void dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter)
+static void dxgi_output_init(struct dxgi_output *output, UINT output_idx,
+        struct dxgi_adapter *adapter)
 {
     output->IDXGIOutput4_iface.lpVtbl = &dxgi_output_vtbl;
     output->refcount = 1;
+    wined3d_adapter_enum_outputs(adapter->wined3d_adapter, output_idx, &output->wined3d_output);
     wined3d_private_store_init(&output->private_store);
     output->adapter = adapter;
     IWineDXGIAdapter_AddRef(&output->adapter->IWineDXGIAdapter_iface);
 }
 
-HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output)
+HRESULT dxgi_output_create(struct dxgi_adapter *adapter, UINT output_idx,
+        struct dxgi_output **output)
 {
     if (!(*output = heap_alloc_zero(sizeof(**output))))
         return E_OUTOFMEMORY;
 
-    dxgi_output_init(*output, adapter);
+    dxgi_output_init(*output, output_idx, adapter);
     return S_OK;
 }
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 4133bedb335..388de0dfe5a 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -155,7 +155,11 @@ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount)
 
 void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
 {
-    wined3d_output_cleanup(&adapter->output);
+    UINT output_idx;
+
+    for (output_idx = 0; output_idx < adapter->output_count; ++output_idx)
+        wined3d_output_cleanup(&adapter->outputs[output_idx]);
+    heap_free(adapter->outputs);
     heap_free(adapter->formats);
 }
 
@@ -885,6 +889,18 @@ UINT CDECL wined3d_get_adapter_count(const struct wined3d *wined3d)
     return wined3d->adapter_count;
 }
 
+HRESULT CDECL wined3d_adapter_enum_outputs(const struct wined3d_adapter *adapter, UINT output_idx,
+        struct wined3d_output **output)
+{
+    TRACE("adapter %p, output_idx %u, output %p.\n", adapter, output_idx, output);
+
+    if (output_idx >= adapter->output_count)
+        return WINED3DERR_INVALIDCALL;
+
+    *output = &adapter->outputs[output_idx];
+    return WINED3D_OK;
+}
+
 UINT CDECL wined3d_adapter_get_output_count(const struct wined3d_adapter *adapter)
 {
     TRACE("adapter %p, reporting %u outputs.\n", adapter, adapter->output_count);
@@ -932,16 +948,6 @@ HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned in
     return WINED3D_OK;
 }
 
-struct wined3d_output * CDECL wined3d_get_adapter_output(const struct wined3d *wined3d, unsigned int adapter_idx)
-{
-    TRACE("wined3d %p, adapter_idx %u.\n", wined3d, adapter_idx);
-
-    if (adapter_idx >= wined3d->adapter_count)
-        return NULL;
-
-    return &wined3d->adapters[adapter_idx]->output;
-}
-
 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
      of the same bpp but different resolutions                                  */
 
@@ -2833,14 +2839,23 @@ BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal,
     HRESULT hr;
 
     adapter->ordinal = ordinal;
+    adapter->formats = NULL;
 
     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 (FAILED(hr = wined3d_output_init(&adapter->output, adapter->device_name)))
+
+    if (!(adapter->outputs = heap_calloc(1, sizeof(*adapter->outputs))))
+    {
+        ERR("Failed to allocate outputs.\n");
+        return FALSE;
+    }
+
+    if (FAILED(hr = wined3d_output_init(&adapter->outputs[0], adapter->device_name)))
     {
         ERR("Failed to initialise output, hr %#x.\n", hr);
+        heap_free(adapter->outputs);
         return FALSE;
     }
     adapter->output_count = 1;
@@ -2848,7 +2863,7 @@ BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal,
     if (!AllocateLocallyUniqueId(&adapter->luid))
     {
         ERR("Failed to set adapter LUID (%#x).\n", GetLastError());
-        wined3d_output_cleanup(&adapter->output);
+        wined3d_adapter_cleanup(adapter);
         return FALSE;
     }
     TRACE("Allocated LUID %08x:%08x for adapter %p.\n",
@@ -2857,7 +2872,6 @@ BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal,
     memset(&adapter->driver_uuid, 0, sizeof(adapter->driver_uuid));
     memset(&adapter->device_uuid, 0, sizeof(adapter->device_uuid));
 
-    adapter->formats = NULL;
     adapter->adapter_ops = adapter_ops;
 
     return TRUE;
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 44b4d22e312..47ec322e83b 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -16,7 +16,6 @@
 @ 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_output(ptr long ptr)
 @ 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)
@@ -26,6 +25,7 @@
 @ cdecl wined3d_set_adapter_display_mode(ptr long ptr)
 @ cdecl wined3d_unregister_windows(ptr)
 
+@ cdecl wined3d_adapter_enum_outputs(ptr long ptr)
 @ cdecl wined3d_adapter_get_output_count(ptr)
 
 @ cdecl wined3d_blend_state_create(ptr ptr ptr ptr ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e2e03683b8c..618b80c8939 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2913,7 +2913,7 @@ struct wined3d_adapter
     struct wined3d_gl_info  gl_info;
     struct wined3d_d3d_info d3d_info;
     struct wined3d_driver_info driver_info;
-    struct wined3d_output output;
+    struct wined3d_output *outputs;
     UINT output_count;
     UINT64 vram_bytes_used;
     GUID driver_uuid;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index fd587934757..948836795b7 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2272,7 +2272,6 @@ 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);
-struct wined3d_output * __cdecl wined3d_get_adapter_output(const struct wined3d *wined3d, unsigned int 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, unsigned int adapter_idx,
@@ -2287,6 +2286,8 @@ HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d,
         UINT adapter_idx, const struct wined3d_display_mode *mode);
 void __cdecl wined3d_unregister_windows(struct wined3d *wined3d);
 
+HRESULT __cdecl wined3d_adapter_enum_outputs(const struct wined3d_adapter *adapter, UINT output_idx,
+        struct wined3d_output **output);
 UINT __cdecl wined3d_adapter_get_output_count(const struct wined3d_adapter *adapter);
 
 HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
-- 
2.20.1




More information about the wine-devel mailing list