[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