diff --git a/dlls/d3d11/async.c b/dlls/d3d11/async.c index 69cc00bfb81..78f01260bee 100644 --- a/dlls/d3d11/async.c +++ b/dlls/d3d11/async.c @@ -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); diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index dc15df690bd..c7b67e57743 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -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; diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index cea1c9da7a0..38d821ae7d1 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -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, }; diff --git a/dlls/d3d9/query.c b/dlls/d3d9/query.c index 9179260ca49..4ca2205576b 100644 --- a/dlls/d3d9/query.c +++ b/dlls/d3d9/query.c @@ -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); diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c index 79e61763a0e..3cfbd8431ac 100644 --- a/dlls/wined3d/query.c +++ b/dlls/wined3d/query.c @@ -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), ×tamp_query_ops, parent); + sizeof(object->timestamp), ×tamp_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), ×tamp_disjoint_query_ops, parent); + sizeof(disjoint_data), ×tamp_disjoint_query_ops, parent, parent_ops); } else { static const UINT64 freq = 1000 * 1000 * 1000; wined3d_query_init(object, device, type, &freq, - sizeof(freq), ×tamp_disjoint_query_ops, parent); + sizeof(freq), ×tamp_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); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 916d2966bdf..4e728f30dfd 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -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) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d628ba549f1..f8ed9aaada6 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -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; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 2966d5e2327..4c0f47dc338 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -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);