Signed-off-by: Józef Kucia jkucia@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,