[PATCH 1/4] wined3d: Make the adapter responsible for creating devices.

Józef Kucia jkucia at codeweavers.com
Thu Apr 18 04:00:20 CDT 2019


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/wined3d/adapter_gl.c      |  33 +++++++++++
 dlls/wined3d/adapter_vk.c      |  42 ++++++++++++++
 dlls/wined3d/device.c          | 100 +++++++++++++++++----------------
 dlls/wined3d/directx.c         |  50 +++++++++++++----
 dlls/wined3d/wined3d_private.h |  10 +++-
 5 files changed, 173 insertions(+), 62 deletions(-)

diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index c195bf4993db..36c29c9a7f58 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4246,6 +4246,37 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter_gl *adapter_gl,
     }
 }
 
+static HRESULT adapter_gl_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter,
+        enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment,
+        const enum wined3d_feature_level *levels, unsigned int level_count,
+        struct wined3d_device_parent *device_parent, struct wined3d_device **device)
+{
+    struct wined3d_device_gl *device_gl;
+    HRESULT hr;
+
+    if (!(device_gl = heap_alloc_zero(sizeof(*device_gl))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = wined3d_device_init(&device_gl->d, wined3d, adapter->ordinal, device_type,
+            focus_window, flags, surface_alignment, levels, level_count, device_parent)))
+    {
+        WARN("Failed to initialize device, hr %#x.\n", hr);
+        heap_free(device_gl);
+        return hr;
+    }
+
+    *device = &device_gl->d;
+    return WINED3D_OK;
+}
+
+static void adapter_gl_destroy_device(struct wined3d_device *device)
+{
+    struct wined3d_device_gl *device_gl = wined3d_device_gl(device);
+
+    wined3d_device_cleanup(&device_gl->d);
+    heap_free(device_gl);
+}
+
 static void adapter_gl_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps)
 {
     const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
@@ -4516,6 +4547,8 @@ static void adapter_gl_destroy(struct wined3d_adapter *adapter)
 static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
 {
     adapter_gl_destroy,
+    adapter_gl_create_device,
+    adapter_gl_destroy_device,
     wined3d_adapter_gl_create_context,
     adapter_gl_get_wined3d_caps,
     adapter_gl_check_format,
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index d8937c2983b4..848c02c52d3b 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -24,6 +24,16 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
+struct wined3d_device_vk
+{
+    struct wined3d_device d;
+};
+
+static inline struct wined3d_device_vk *wined3d_device_vk(struct wined3d_device *device)
+{
+    return CONTAINING_RECORD(device, struct wined3d_device_vk, d);
+}
+
 static inline const struct wined3d_adapter_vk *wined3d_adapter_vk_const(const struct wined3d_adapter *adapter)
 {
     return CONTAINING_RECORD(adapter, struct wined3d_adapter_vk, a);
@@ -96,6 +106,36 @@ static void adapter_vk_destroy(struct wined3d_adapter *adapter)
     heap_free(adapter_vk);
 }
 
+static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter,
+        enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment,
+        const enum wined3d_feature_level *levels, unsigned int level_count,
+        struct wined3d_device_parent *device_parent, struct wined3d_device **device)
+{
+    struct wined3d_device_vk *device_vk;
+    HRESULT hr;
+
+    if (!(device_vk = heap_alloc_zero(sizeof(*device_vk))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = wined3d_device_init(&device_vk->d, wined3d, adapter->ordinal, device_type,
+            focus_window, flags, surface_alignment, levels, level_count, device_parent)))
+    {
+        WARN("Failed to initialize device, hr %#x.\n", hr);
+        heap_free(device_vk);
+        return hr;
+    }
+
+    return WINED3D_OK;
+}
+
+static void adapter_vk_destroy_device(struct wined3d_device *device)
+{
+    struct wined3d_device_vk *device_vk = wined3d_device_vk(device);
+
+    wined3d_device_cleanup(device);
+    heap_free(device_vk);
+}
+
 static BOOL adapter_vk_create_context(struct wined3d_context *context,
         struct wined3d_texture *target, const struct wined3d_format *ds_format)
 {
@@ -210,6 +250,8 @@ static BOOL adapter_vk_check_format(const struct wined3d_adapter *adapter,
 static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
 {
     adapter_vk_destroy,
+    adapter_vk_create_device,
+    adapter_vk_destroy_device,
     adapter_vk_create_context,
     adapter_vk_get_wined3d_caps,
     adapter_vk_check_format,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 361ac6b1e360..23ba41c56b48 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -476,6 +476,54 @@ static void device_leftover_sampler(struct wine_rb_entry *entry, void *context)
     ERR("Leftover sampler %p.\n", sampler);
 }
 
+void wined3d_device_cleanup(struct wined3d_device *device)
+{
+    unsigned int i;
+
+    if (device->swapchain_count)
+        wined3d_device_uninit_3d(device);
+
+    wined3d_stateblock_state_cleanup(&device->stateblock_state);
+
+    wined3d_cs_destroy(device->cs);
+
+    if (device->recording && wined3d_stateblock_decref(device->recording))
+        ERR("Something's still holding the recording stateblock.\n");
+    device->recording = NULL;
+
+    state_cleanup(&device->state);
+
+    for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
+    {
+        heap_free(device->multistate_funcs[i]);
+        device->multistate_funcs[i] = NULL;
+    }
+
+    if (!list_empty(&device->resources))
+    {
+        struct wined3d_resource *resource;
+
+        ERR("Device released with resources still bound.\n");
+
+        LIST_FOR_EACH_ENTRY(resource, &device->resources, struct wined3d_resource, resource_list_entry)
+        {
+            ERR("Leftover resource %p with type %s (%#x).\n",
+                    resource, debug_d3dresourcetype(resource->type), resource->type);
+        }
+    }
+
+    if (device->contexts)
+        ERR("Context array not freed!\n");
+    if (device->hardwareCursor)
+        DestroyCursor(device->hardwareCursor);
+    device->hardwareCursor = 0;
+
+    wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL);
+
+    wined3d_decref(device->wined3d);
+    device->wined3d = NULL;
+}
+
 ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
 {
     ULONG refcount = InterlockedDecrement(&device->ref);
@@ -484,52 +532,8 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
 
     if (!refcount)
     {
-        UINT i;
-
-        if (device->swapchain_count)
-            wined3d_device_uninit_3d(device);
-
-        wined3d_stateblock_state_cleanup(&device->stateblock_state);
-
-        wined3d_cs_destroy(device->cs);
-
-        if (device->recording && wined3d_stateblock_decref(device->recording))
-            ERR("Something's still holding the recording stateblock.\n");
-        device->recording = NULL;
-
-        state_cleanup(&device->state);
-
-        for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
-        {
-            heap_free(device->multistate_funcs[i]);
-            device->multistate_funcs[i] = NULL;
-        }
-
-        if (!list_empty(&device->resources))
-        {
-            struct wined3d_resource *resource;
-
-            ERR("Device released with resources still bound.\n");
-
-            LIST_FOR_EACH_ENTRY(resource, &device->resources, struct wined3d_resource, resource_list_entry)
-            {
-                ERR("Leftover resource %p with type %s (%#x).\n",
-                        resource, debug_d3dresourcetype(resource->type), resource->type);
-            }
-        }
-
-        if (device->contexts)
-            ERR("Context array not freed!\n");
-        if (device->hardwareCursor)
-            DestroyCursor(device->hardwareCursor);
-        device->hardwareCursor = 0;
-
-        wine_rb_destroy(&device->samplers, device_leftover_sampler, NULL);
-
-        wined3d_decref(device->wined3d);
-        device->wined3d = NULL;
-        heap_free(wined3d_device_gl(device));
-        TRACE("Freed device %p.\n", device);
+        device->adapter->adapter_ops->adapter_destroy_device(device);
+        TRACE("Destroyed device %p.\n", device);
     }
 
     return refcount;
@@ -5271,8 +5275,8 @@ static BOOL wined3d_select_feature_level(const struct wined3d_adapter *adapter,
     return FALSE;
 }
 
-HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
-        UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
+HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined3d,
+        unsigned int adapter_idx, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags,
         BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count,
         struct wined3d_device_parent *device_parent)
 {
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index e21b8beaa884..3c89fad7d1a1 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2169,7 +2169,8 @@ HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, unsigned int adapte
         const enum wined3d_feature_level *feature_levels, unsigned int feature_level_count,
         struct wined3d_device_parent *device_parent, struct wined3d_device **device)
 {
-    struct wined3d_device_gl *device_gl;
+    const struct wined3d_adapter *adapter;
+    struct wined3d_device *object;
     HRESULT hr;
 
     TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, "
@@ -2180,20 +2181,14 @@ HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, unsigned int adapte
     if (adapter_idx >= wined3d->adapter_count)
         return WINED3DERR_INVALIDCALL;
 
-    if (!(device_gl = heap_alloc_zero(sizeof(*device_gl))))
-        return E_OUTOFMEMORY;
-
-    if (FAILED(hr = device_init(&device_gl->d, wined3d, adapter_idx,
+    adapter = wined3d->adapters[adapter_idx];
+    if (FAILED(hr = adapter->adapter_ops->adapter_create_device(wined3d, adapter,
             device_type, focus_window, flags, surface_alignment,
-            feature_levels, feature_level_count, device_parent)))
-    {
-        WARN("Failed to initialize device, hr %#x.\n", hr);
-        heap_free(device_gl);
+            feature_levels, feature_level_count, device_parent, &object)))
         return hr;
-    }
 
-    TRACE("Created device %p.\n", device_gl);
-    *device = &device_gl->d;
+    TRACE("Created device %p.\n", object);
+    *device = object;
 
     device_parent->ops->wined3d_device_created(device_parent, *device);
 
@@ -2206,6 +2201,35 @@ static void adapter_no3d_destroy(struct wined3d_adapter *adapter)
     heap_free(adapter);
 }
 
+static HRESULT adapter_no3d_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter,
+        enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment,
+        const enum wined3d_feature_level *levels, unsigned int level_count,
+        struct wined3d_device_parent *device_parent, struct wined3d_device **device)
+{
+    struct wined3d_device *object;
+    HRESULT hr;
+
+    if (!(object = heap_alloc_zero(sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = wined3d_device_init(object, wined3d, adapter->ordinal, device_type,
+            focus_window, flags, surface_alignment, levels, level_count, device_parent)))
+    {
+        WARN("Failed to initialize device, hr %#x.\n", hr);
+        heap_free(object);
+        return hr;
+    }
+
+    *device = object;
+    return WINED3D_OK;
+}
+
+static void adapter_no3d_destroy_device(struct wined3d_device *device)
+{
+    wined3d_device_cleanup(device);
+    heap_free(device);
+}
+
 static BOOL wined3d_adapter_no3d_create_context(struct wined3d_context *context,
         struct wined3d_texture *target, const struct wined3d_format *ds_format)
 {
@@ -2226,6 +2250,8 @@ static BOOL adapter_no3d_check_format(const struct wined3d_adapter *adapter,
 static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
 {
     adapter_no3d_destroy,
+    adapter_no3d_create_device,
+    adapter_no3d_destroy_device,
     wined3d_adapter_no3d_create_context,
     adapter_no3d_get_wined3d_caps,
     adapter_no3d_check_format,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9f63f3d8d628..15876e4f1edc 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2691,6 +2691,11 @@ void wined3d_driver_info_init(struct wined3d_driver_info *driver_info,
 struct wined3d_adapter_ops
 {
     void (*adapter_destroy)(struct wined3d_adapter *adapter);
+    HRESULT (*adapter_create_device)(struct wined3d *wined3d, const struct wined3d_adapter *adapter,
+            enum wined3d_device_type device_type, HWND focus_window, unsigned int flags,
+            BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count,
+            struct wined3d_device_parent *device_parent, struct wined3d_device **device);
+    void (*adapter_destroy_device)(struct wined3d_device *device);
     BOOL (*adapter_create_context)(struct wined3d_context *context,
             struct wined3d_texture *target, const struct wined3d_format *ds_format);
     void (*adapter_get_wined3d_caps)(const struct wined3d_adapter *adapter, struct wined3d_caps *caps);
@@ -3163,13 +3168,14 @@ struct wined3d_device
     UINT context_count;
 };
 
+void wined3d_device_cleanup(struct wined3d_device *device) DECLSPEC_HIDDEN;
 void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb,
         UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags,
         const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
 BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
 void device_context_remove(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
-HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
-        UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
+HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined3d,
+        unsigned int adapter_idx, enum wined3d_device_type device_type, HWND focus_window, unsigned int flags,
         BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count,
         struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN;
 LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
-- 
2.21.0




More information about the wine-devel mailing list