[PATCH 1/5] wined3d: Initialise outputs in wined3d_init().

Zhiyi Zhang zzhang at codeweavers.com
Mon Feb 10 02:19:19 CST 2020


Place all outputs in struct wined3d so that D3D9 and older
versions of D3D can index into outputs as adapters because
older versions of D3D treat outputs as adapters. And put
outputs to the adapters they belong to so that DXGI can
find the outputs of an adapter as well.

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/wined3d/directx.c         | 82 +++++++++++++++++++++++++---------
 dlls/wined3d/wined3d_main.c    |  2 +-
 dlls/wined3d/wined3d_private.h | 12 +++--
 3 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 7167f208e9..3d676f7e10 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -26,6 +26,7 @@
 
 #include "wined3d_private.h"
 #include "winternl.h"
+#include "wine/heap.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
@@ -155,7 +156,6 @@ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount)
 
 void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
 {
-    wined3d_output_cleanup(&adapter->output);
     heap_free(adapter->formats);
 }
 
@@ -168,6 +168,32 @@ ULONG CDECL wined3d_incref(struct wined3d *wined3d)
     return refcount;
 }
 
+static void wined3d_cleanup(struct wined3d *wined3d)
+{
+    unsigned int i;
+
+    if (wined3d->outputs)
+    {
+        for (i = 0; i < wined3d->output_count; ++i)
+            wined3d_output_cleanup(&wined3d->outputs[i]);
+    }
+
+    if (wined3d->adapters)
+    {
+        for (i = 0; i < wined3d->adapter_count; ++i)
+        {
+            struct wined3d_adapter *adapter = wined3d->adapters[i];
+            if (!adapter)
+                break;
+
+            adapter->adapter_ops->adapter_destroy(adapter);
+        }
+    }
+
+    heap_free(wined3d->outputs);
+    heap_free(wined3d->adapters);
+}
+
 ULONG CDECL wined3d_decref(struct wined3d *wined3d)
 {
     ULONG refcount = InterlockedDecrement(&wined3d->ref);
@@ -176,14 +202,7 @@ ULONG CDECL wined3d_decref(struct wined3d *wined3d)
 
     if (!refcount)
     {
-        unsigned int i;
-
-        for (i = 0; i < wined3d->adapter_count; ++i)
-        {
-            struct wined3d_adapter *adapter = wined3d->adapters[i];
-
-            adapter->adapter_ops->adapter_destroy(adapter);
-        }
+        wined3d_cleanup(wined3d);
         heap_free(wined3d);
     }
 
@@ -920,7 +939,7 @@ struct wined3d_output * CDECL wined3d_get_adapter_output(const struct wined3d *w
     if (adapter_idx >= wined3d->adapter_count)
         return NULL;
 
-    return &wined3d->adapters[adapter_idx]->output;
+    return &wined3d->adapters[adapter_idx]->outputs[0];
 }
 
 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
@@ -2811,7 +2830,6 @@ BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal,
         const struct wined3d_adapter_ops *adapter_ops)
 {
     DISPLAY_DEVICEW display_device;
-    HRESULT hr;
 
     adapter->ordinal = ordinal;
 
@@ -2819,16 +2837,10 @@ BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int ordinal,
     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)))
-    {
-        ERR("Failed to initialise output, hr %#x.\n", hr);
-        return FALSE;
-    }
 
     if (!AllocateLocallyUniqueId(&adapter->luid))
     {
         ERR("Failed to set adapter LUID (%#x).\n", GetLastError());
-        wined3d_output_cleanup(&adapter->output);
         return FALSE;
     }
     TRACE("Allocated LUID %08x:%08x for adapter %p.\n",
@@ -2863,17 +2875,45 @@ const struct wined3d_parent_ops wined3d_null_parent_ops =
 
 HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags)
 {
+    HRESULT hr = E_FAIL;
+
     wined3d->ref = 1;
     wined3d->flags = flags;
 
-    TRACE("Initialising adapters.\n");
+    TRACE("Initialising adapters and outputs.\n");
+
+    wined3d->adapter_count = 1;
+    wined3d->output_count = 1;
+
+    wined3d->adapters = heap_calloc(wined3d->adapter_count, sizeof(*wined3d->adapters));
+    if (!wined3d->adapters)
+        goto fail;
+
+    wined3d->outputs = heap_calloc(wined3d->output_count, sizeof(*wined3d->outputs));
+    if (!wined3d->outputs)
+        goto fail;
 
     if (!(wined3d->adapters[0] = wined3d_adapter_create(0, flags)))
     {
         WARN("Failed to create adapter.\n");
-        return E_FAIL;
+        goto fail;
     }
-    wined3d->adapter_count = 1;
 
-    return WINED3D_OK;
+    wined3d->adapters[0]->outputs = wined3d->outputs;
+    wined3d->adapters[0]->output_count = 1;
+    if (FAILED(hr = wined3d_output_init(&wined3d->outputs[0], wined3d->adapters[0]->device_name)))
+    {
+        WARN("Failed to create output, hr %#x.\n", hr);
+        goto fail;
+    }
+
+    TRACE("adapter count: %u, output count: %u.\n", wined3d->adapter_count, wined3d->output_count);
+    hr = WINED3D_OK;
+fail:
+    if (FAILED(hr))
+    {
+        ERR("Initialising wined3d failed!\n");
+        wined3d_cleanup(wined3d);
+    }
+    return hr;
 }
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index 05684aeb3b..3e20028b81 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -126,7 +126,7 @@ struct wined3d * CDECL wined3d_create(DWORD flags)
     struct wined3d *object;
     HRESULT hr;
 
-    if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d, adapters[1]))))
+    if (!(object = heap_alloc_zero(sizeof(*object))))
     {
         ERR("Failed to allocate wined3d object memory.\n");
         return NULL;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0e1e55d52b..c7ace57324 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2893,6 +2893,7 @@ struct wined3d_adapter_ops
             struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value);
 };
 
+/* The output structure, represents a video card output */
 struct wined3d_output
 {
     D3DKMT_HANDLE kmt_adapter;
@@ -2900,7 +2901,7 @@ struct wined3d_output
     D3DDDI_VIDEO_PRESENT_SOURCE_ID vidpn_source_id;
 };
 
-/* The adapter structure */
+/* The adapter structure, represents a video card */
 struct wined3d_adapter
 {
     unsigned int ordinal;
@@ -2910,7 +2911,10 @@ 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;     /* Outputs in this adapter */
+    unsigned int output_count;
+
     UINT64 vram_bytes_used;
     GUID driver_uuid;
     GUID device_uuid;
@@ -3117,7 +3121,9 @@ struct wined3d
     LONG ref;
     unsigned int flags;
     unsigned int adapter_count;
-    struct wined3d_adapter *adapters[1];
+    struct wined3d_adapter **adapters;
+    unsigned int output_count;
+    struct wined3d_output *outputs;     /* Outputs of all adapters, d3d8/9 treat outputs as adapters */
 };
 
 BOOL wined3d_filter_messages(HWND window, BOOL filter) DECLSPEC_HIDDEN;
-- 
2.20.1




More information about the wine-devel mailing list