wined3d: Make the adapter responsible for creating devices.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2019-04-18 11:00:20 +02:00 committed by Alexandre Julliard
parent 7f95ed7cd2
commit 32c3afba51
5 changed files with 173 additions and 62 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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)
{

View File

@ -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,

View File

@ -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,