[PATCH 5/7] wined3d: Add "parent_ops" for query objects.
Józef Kucia
jkucia at codeweavers.com
Wed May 10 08:54:07 CDT 2017
In order to implement proper refcounting for
d3d11_immediate_context_SetPredication().
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
dlls/d3d11/async.c | 32 ++++++++++++++++++++----
dlls/d3d9/d3d9_private.h | 4 ++-
dlls/d3d9/device.c | 2 +-
dlls/d3d9/query.c | 3 ++-
dlls/wined3d/query.c | 55 ++++++++++++++++++++++++++----------------
dlls/wined3d/wined3d.spec | 2 +-
dlls/wined3d/wined3d_private.h | 1 +
include/wine/wined3d.h | 4 +--
8 files changed, 71 insertions(+), 32 deletions(-)
diff --git a/dlls/d3d11/async.c b/dlls/d3d11/async.c
index 69cc00b..78f0126 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 dc15df6..c7b67e5 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 cea1c9d..38d821a 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 9179260..4ca2205 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 79e6176..3cfbd84 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 916d296..4e728f3 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 d628ba5..f8ed9aa 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 2966d5e..4c0f47d 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);
--
2.10.2
More information about the wine-patches
mailing list