[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), &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);
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