wined3d: Add "parent_ops" for query objects.

In order to implement proper refcounting for
d3d11_immediate_context_SetPredication().

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 2017-05-10 15:54:07 +02:00 committed by Alexandre Julliard
parent febf242ff5
commit 6c5a90e193
8 changed files with 71 additions and 32 deletions

View File

@ -71,6 +71,14 @@ static ULONG STDMETHODCALLTYPE d3d11_query_AddRef(ID3D11Query *iface)
TRACE("%p increasing refcount to %u.\n", query, refcount);
if (refcount == 1)
{
ID3D11Device_AddRef(query->device);
wined3d_mutex_lock();
wined3d_query_incref(query->wined3d_query);
wined3d_mutex_unlock();
}
return refcount;
}
@ -83,12 +91,13 @@ static ULONG STDMETHODCALLTYPE d3d11_query_Release(ID3D11Query *iface)
if (!refcount)
{
ID3D11Device_Release(query->device);
ID3D11Device *device = query->device;
wined3d_mutex_lock();
wined3d_query_decref(query->wined3d_query);
wined3d_private_store_cleanup(&query->private_store);
wined3d_mutex_unlock();
HeapFree(GetProcessHeap(), 0, query);
ID3D11Device_Release(device);
}
return refcount;
@ -170,6 +179,19 @@ static const struct ID3D11QueryVtbl d3d11_query_vtbl =
d3d11_query_GetDesc,
};
static void STDMETHODCALLTYPE d3d_query_wined3d_object_destroyed(void *parent)
{
struct d3d_query *query = parent;
wined3d_private_store_cleanup(&query->private_store);
HeapFree(GetProcessHeap(), 0, parent);
}
static const struct wined3d_parent_ops d3d_query_wined3d_parent_ops =
{
d3d_query_wined3d_object_destroyed,
};
struct d3d_query *unsafe_impl_from_ID3D11Query(ID3D11Query *iface)
{
if (!iface)
@ -401,8 +423,8 @@ static HRESULT d3d_query_init(struct d3d_query *query, struct d3d_device *device
wined3d_mutex_lock();
wined3d_private_store_init(&query->private_store);
if (FAILED(hr = wined3d_query_create(device->wined3d_device,
query_type_map[desc->Query], query, &query->wined3d_query)))
if (FAILED(hr = wined3d_query_create(device->wined3d_device, query_type_map[desc->Query],
query, &d3d_query_wined3d_parent_ops, &query->wined3d_query)))
{
WARN("Failed to create wined3d query, hr %#x.\n", hr);
wined3d_private_store_cleanup(&query->private_store);

View File

@ -41,7 +41,9 @@
#define D3DPRESENTFLAGS_MASK 0x00000fffu
extern HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN;
extern const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops DECLSPEC_HIDDEN;
HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN;
D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;

View File

@ -27,7 +27,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
static void STDMETHODCALLTYPE d3d9_null_wined3d_object_destroyed(void *parent) {}
static const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops =
const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops =
{
d3d9_null_wined3d_object_destroyed,
};

View File

@ -189,7 +189,8 @@ HRESULT query_init(struct d3d9_query *query, struct d3d9_device *device, D3DQUER
query->refcount = 1;
wined3d_mutex_lock();
if (FAILED(hr = wined3d_query_create(device->wined3d_device, type, query, &query->wined3d_query)))
if (FAILED(hr = wined3d_query_create(device->wined3d_device, type,
query, &d3d9_null_wined3d_parent_ops, &query->wined3d_query)))
{
wined3d_mutex_unlock();
WARN("Failed to create wined3d query, hr %#x.\n", hr);

View File

@ -27,10 +27,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
static void wined3d_query_init(struct wined3d_query *query, struct wined3d_device *device,
enum wined3d_query_type type, const void *data, DWORD data_size,
const struct wined3d_query_ops *query_ops, void *parent)
const struct wined3d_query_ops *query_ops, void *parent, const struct wined3d_parent_ops *parent_ops)
{
query->ref = 1;
query->parent = parent;
query->parent_ops = parent_ops;
query->device = device;
query->state = QUERY_CREATED;
query->type = type;
@ -306,7 +307,10 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query)
TRACE("%p decreasing refcount to %u.\n", query, refcount);
if (!refcount)
{
query->parent_ops->wined3d_object_destroyed(query->parent);
wined3d_cs_destroy_object(query->device->cs, wined3d_query_destroy_object, query);
}
return refcount;
}
@ -640,12 +644,14 @@ static const struct wined3d_query_ops event_query_ops =
};
static HRESULT wined3d_event_query_create(struct wined3d_device *device,
enum wined3d_query_type type, void *parent, struct wined3d_query **query)
enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_query **query)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_event_query *object;
TRACE("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query);
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
if (!wined3d_event_query_supported(gl_info))
{
@ -657,7 +663,7 @@ static HRESULT wined3d_event_query_create(struct wined3d_device *device,
return E_OUTOFMEMORY;
wined3d_query_init(&object->query, device, type, &object->signalled,
sizeof(object->signalled), &event_query_ops, parent);
sizeof(object->signalled), &event_query_ops, parent, parent_ops);
TRACE("Created query %p.\n", object);
*query = &object->query;
@ -672,12 +678,14 @@ static const struct wined3d_query_ops occlusion_query_ops =
};
static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device,
enum wined3d_query_type type, void *parent, struct wined3d_query **query)
enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_query **query)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_occlusion_query *object;
TRACE("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query);
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
if (!gl_info->supported[ARB_OCCLUSION_QUERY])
{
@ -689,7 +697,7 @@ static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device,
return E_OUTOFMEMORY;
wined3d_query_init(&object->query, device, type, &object->samples,
sizeof(object->samples), &occlusion_query_ops, parent);
sizeof(object->samples), &occlusion_query_ops, parent, parent_ops);
TRACE("Created query %p.\n", object);
*query = &object->query;
@ -704,12 +712,14 @@ static const struct wined3d_query_ops timestamp_query_ops =
};
static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device,
enum wined3d_query_type type, void *parent, struct wined3d_query **query)
enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_query **query)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_timestamp_query *object;
TRACE("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query);
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
if (!gl_info->supported[ARB_TIMER_QUERY])
{
@ -721,7 +731,7 @@ static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device,
return E_OUTOFMEMORY;
wined3d_query_init(&object->query, device, type, &object->timestamp,
sizeof(object->timestamp), &timestamp_query_ops, parent);
sizeof(object->timestamp), &timestamp_query_ops, parent, parent_ops);
TRACE("Created query %p.\n", object);
*query = &object->query;
@ -736,12 +746,14 @@ static const struct wined3d_query_ops timestamp_disjoint_query_ops =
};
static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *device,
enum wined3d_query_type type, void *parent, struct wined3d_query **query)
enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_query **query)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_query *object;
TRACE("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query);
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
if (!gl_info->supported[ARB_TIMER_QUERY])
{
@ -757,14 +769,14 @@ static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *de
static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE};
wined3d_query_init(object, device, type, &disjoint_data,
sizeof(disjoint_data), &timestamp_disjoint_query_ops, parent);
sizeof(disjoint_data), &timestamp_disjoint_query_ops, parent, parent_ops);
}
else
{
static const UINT64 freq = 1000 * 1000 * 1000;
wined3d_query_init(object, device, type, &freq,
sizeof(freq), &timestamp_disjoint_query_ops, parent);
sizeof(freq), &timestamp_disjoint_query_ops, parent, parent_ops);
}
TRACE("Created query %p.\n", object);
@ -773,25 +785,26 @@ static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *de
return WINED3D_OK;
}
HRESULT CDECL wined3d_query_create(struct wined3d_device *device,
enum wined3d_query_type type, void *parent, struct wined3d_query **query)
HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
{
TRACE("device %p, type %#x, parent %p, query %p.\n", device, type, parent, query);
TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
device, type, parent, parent_ops, query);
switch (type)
{
case WINED3D_QUERY_TYPE_EVENT:
return wined3d_event_query_create(device, type, parent, query);
return wined3d_event_query_create(device, type, parent, parent_ops, query);
case WINED3D_QUERY_TYPE_OCCLUSION:
return wined3d_occlusion_query_create(device, type, parent, query);
return wined3d_occlusion_query_create(device, type, parent, parent_ops, query);
case WINED3D_QUERY_TYPE_TIMESTAMP:
return wined3d_timestamp_query_create(device, type, parent, query);
return wined3d_timestamp_query_create(device, type, parent, parent_ops, query);
case WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT:
case WINED3D_QUERY_TYPE_TIMESTAMP_FREQ:
return wined3d_timestamp_disjoint_query_create(device, type, parent, query);
return wined3d_timestamp_disjoint_query_create(device, type, parent, parent_ops, query);
default:
FIXME("Unhandled query type %#x.\n", type);

View File

@ -198,7 +198,7 @@
@ cdecl wined3d_palette_incref(ptr)
@ cdecl wined3d_palette_set_entries(ptr long long long ptr)
@ cdecl wined3d_query_create(ptr long ptr ptr)
@ cdecl wined3d_query_create(ptr long ptr ptr ptr)
@ cdecl wined3d_query_decref(ptr)
@ cdecl wined3d_query_get_data(ptr ptr long long)
@ cdecl wined3d_query_get_data_size(ptr)

View File

@ -1583,6 +1583,7 @@ struct wined3d_query
LONG ref;
void *parent;
const struct wined3d_parent_ops *parent_ops;
struct wined3d_device *device;
enum wined3d_query_state state;
enum wined3d_query_type type;

View File

@ -2425,8 +2425,8 @@ ULONG __cdecl wined3d_palette_incref(struct wined3d_palette *palette);
HRESULT __cdecl wined3d_palette_set_entries(struct wined3d_palette *palette,
DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries);
HRESULT __cdecl wined3d_query_create(struct wined3d_device *device,
enum wined3d_query_type type, void *parent, struct wined3d_query **query);
HRESULT __cdecl wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query);
ULONG __cdecl wined3d_query_decref(struct wined3d_query *query);
HRESULT __cdecl wined3d_query_get_data(struct wined3d_query *query, void *data, UINT data_size, DWORD flags);
UINT __cdecl wined3d_query_get_data_size(const struct wined3d_query *query);