regedit: Read registry value information before exporting.
[wine.git] / dlls / d3d11 / async.c
blobef8e63c144f1cb2756377b5fe8c519b5c93b73e4
1 /*
2 * Copyright 2009 Henri Verbeet for CodeWeavers
3 * Copyright 2015-2017 Józef Kucia for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include "d3d11_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
28 /* ID3D11Query methods */
30 static inline struct d3d_query *impl_from_ID3D11Query(ID3D11Query *iface)
32 return CONTAINING_RECORD(iface, struct d3d_query, ID3D11Query_iface);
35 static HRESULT STDMETHODCALLTYPE d3d11_query_QueryInterface(ID3D11Query *iface, REFIID riid, void **object)
37 struct d3d_query *query = impl_from_ID3D11Query(iface);
39 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
41 if ((IsEqualGUID(riid, &IID_ID3D11Predicate) && query->predicate)
42 || IsEqualGUID(riid, &IID_ID3D11Query)
43 || IsEqualGUID(riid, &IID_ID3D11Asynchronous)
44 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
45 || IsEqualGUID(riid, &IID_IUnknown))
47 ID3D11Query_AddRef(iface);
48 *object = iface;
49 return S_OK;
52 if ((IsEqualGUID(riid, &IID_ID3D10Predicate) && query->predicate)
53 || IsEqualGUID(riid, &IID_ID3D10Query)
54 || IsEqualGUID(riid, &IID_ID3D10Asynchronous)
55 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
57 ID3D10Query_AddRef(&query->ID3D10Query_iface);
58 *object = &query->ID3D10Query_iface;
59 return S_OK;
62 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
64 *object = NULL;
65 return E_NOINTERFACE;
68 static ULONG STDMETHODCALLTYPE d3d11_query_AddRef(ID3D11Query *iface)
70 struct d3d_query *query = impl_from_ID3D11Query(iface);
71 ULONG refcount = InterlockedIncrement(&query->refcount);
73 TRACE("%p increasing refcount to %u.\n", query, refcount);
75 if (refcount == 1)
77 ID3D11Device_AddRef(query->device);
78 wined3d_mutex_lock();
79 wined3d_query_incref(query->wined3d_query);
80 wined3d_mutex_unlock();
83 return refcount;
86 static ULONG STDMETHODCALLTYPE d3d11_query_Release(ID3D11Query *iface)
88 struct d3d_query *query = impl_from_ID3D11Query(iface);
89 ULONG refcount = InterlockedDecrement(&query->refcount);
91 TRACE("%p decreasing refcount to %u.\n", query, refcount);
93 if (!refcount)
95 ID3D11Device *device = query->device;
97 wined3d_mutex_lock();
98 wined3d_query_decref(query->wined3d_query);
99 wined3d_mutex_unlock();
101 ID3D11Device_Release(device);
104 return refcount;
107 static void STDMETHODCALLTYPE d3d11_query_GetDevice(ID3D11Query *iface, ID3D11Device **device)
109 struct d3d_query *query = impl_from_ID3D11Query(iface);
111 TRACE("iface %p, device %p.\n", iface, device);
113 *device = query->device;
114 ID3D11Device_AddRef(*device);
117 static HRESULT STDMETHODCALLTYPE d3d11_query_GetPrivateData(ID3D11Query *iface,
118 REFGUID guid, UINT *data_size, void *data)
120 struct d3d_query *query = impl_from_ID3D11Query(iface);
122 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
124 return d3d_get_private_data(&query->private_store, guid, data_size, data);
127 static HRESULT STDMETHODCALLTYPE d3d11_query_SetPrivateData(ID3D11Query *iface,
128 REFGUID guid, UINT data_size, const void *data)
130 struct d3d_query *query = impl_from_ID3D11Query(iface);
132 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
134 return d3d_set_private_data(&query->private_store, guid, data_size, data);
137 static HRESULT STDMETHODCALLTYPE d3d11_query_SetPrivateDataInterface(ID3D11Query *iface,
138 REFGUID guid, const IUnknown *data)
140 struct d3d_query *query = impl_from_ID3D11Query(iface);
142 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
144 return d3d_set_private_data_interface(&query->private_store, guid, data);
147 static UINT STDMETHODCALLTYPE d3d11_query_GetDataSize(ID3D11Query *iface)
149 struct d3d_query *query = impl_from_ID3D11Query(iface);
150 unsigned int data_size;
152 TRACE("iface %p.\n", iface);
154 wined3d_mutex_lock();
155 data_size = wined3d_query_get_data_size(query->wined3d_query);
156 wined3d_mutex_unlock();
158 return data_size;
161 static void STDMETHODCALLTYPE d3d11_query_GetDesc(ID3D11Query *iface, D3D11_QUERY_DESC *desc)
163 struct d3d_query *query = impl_from_ID3D11Query(iface);
165 TRACE("iface %p, desc %p.\n", iface, desc);
167 *desc = query->desc;
170 static const struct ID3D11QueryVtbl d3d11_query_vtbl =
172 /* IUnknown methods */
173 d3d11_query_QueryInterface,
174 d3d11_query_AddRef,
175 d3d11_query_Release,
176 /* ID3D11DeviceChild methods */
177 d3d11_query_GetDevice,
178 d3d11_query_GetPrivateData,
179 d3d11_query_SetPrivateData,
180 d3d11_query_SetPrivateDataInterface,
181 /* ID3D11Asynchronous methods */
182 d3d11_query_GetDataSize,
183 /* ID3D11Query methods */
184 d3d11_query_GetDesc,
187 static void STDMETHODCALLTYPE d3d_query_wined3d_object_destroyed(void *parent)
189 struct d3d_query *query = parent;
191 wined3d_private_store_cleanup(&query->private_store);
192 HeapFree(GetProcessHeap(), 0, parent);
195 static const struct wined3d_parent_ops d3d_query_wined3d_parent_ops =
197 d3d_query_wined3d_object_destroyed,
200 struct d3d_query *unsafe_impl_from_ID3D11Query(ID3D11Query *iface)
202 if (!iface)
203 return NULL;
204 assert(iface->lpVtbl == &d3d11_query_vtbl);
205 return CONTAINING_RECORD(iface, struct d3d_query, ID3D11Query_iface);
208 struct d3d_query *unsafe_impl_from_ID3D11Asynchronous(ID3D11Asynchronous *iface)
210 return unsafe_impl_from_ID3D11Query((ID3D11Query *)iface);
213 /* ID3D10Query methods */
215 static inline struct d3d_query *impl_from_ID3D10Query(ID3D10Query *iface)
217 return CONTAINING_RECORD(iface, struct d3d_query, ID3D10Query_iface);
220 /* IUnknown methods */
222 static HRESULT STDMETHODCALLTYPE d3d10_query_QueryInterface(ID3D10Query *iface, REFIID riid, void **object)
224 struct d3d_query *query = impl_from_ID3D10Query(iface);
226 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
228 return d3d11_query_QueryInterface(&query->ID3D11Query_iface, riid, object);
231 static ULONG STDMETHODCALLTYPE d3d10_query_AddRef(ID3D10Query *iface)
233 struct d3d_query *query = impl_from_ID3D10Query(iface);
235 TRACE("iface %p.\n", iface);
237 return d3d11_query_AddRef(&query->ID3D11Query_iface);
240 static ULONG STDMETHODCALLTYPE d3d10_query_Release(ID3D10Query *iface)
242 struct d3d_query *query = impl_from_ID3D10Query(iface);
244 TRACE("iface %p.\n", iface);
246 return d3d11_query_Release(&query->ID3D11Query_iface);
249 /* ID3D10DeviceChild methods */
251 static void STDMETHODCALLTYPE d3d10_query_GetDevice(ID3D10Query *iface, ID3D10Device **device)
253 struct d3d_query *query = impl_from_ID3D10Query(iface);
255 TRACE("iface %p, device %p.\n", iface, device);
257 ID3D11Device_QueryInterface(query->device, &IID_ID3D10Device, (void **)device);
260 static HRESULT STDMETHODCALLTYPE d3d10_query_GetPrivateData(ID3D10Query *iface,
261 REFGUID guid, UINT *data_size, void *data)
263 struct d3d_query *query = impl_from_ID3D10Query(iface);
265 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
266 iface, debugstr_guid(guid), data_size, data);
268 return d3d_get_private_data(&query->private_store, guid, data_size, data);
271 static HRESULT STDMETHODCALLTYPE d3d10_query_SetPrivateData(ID3D10Query *iface,
272 REFGUID guid, UINT data_size, const void *data)
274 struct d3d_query *query = impl_from_ID3D10Query(iface);
276 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
277 iface, debugstr_guid(guid), data_size, data);
279 return d3d_set_private_data(&query->private_store, guid, data_size, data);
282 static HRESULT STDMETHODCALLTYPE d3d10_query_SetPrivateDataInterface(ID3D10Query *iface,
283 REFGUID guid, const IUnknown *data)
285 struct d3d_query *query = impl_from_ID3D10Query(iface);
287 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
289 return d3d_set_private_data_interface(&query->private_store, guid, data);
292 /* ID3D10Asynchronous methods */
294 static void STDMETHODCALLTYPE d3d10_query_Begin(ID3D10Query *iface)
296 struct d3d_query *query = impl_from_ID3D10Query(iface);
297 HRESULT hr;
299 TRACE("iface %p.\n", iface);
301 wined3d_mutex_lock();
302 if (FAILED(hr = wined3d_query_issue(query->wined3d_query, WINED3DISSUE_BEGIN)))
303 ERR("Failed to issue query, hr %#x.\n", hr);
304 wined3d_mutex_unlock();
307 static void STDMETHODCALLTYPE d3d10_query_End(ID3D10Query *iface)
309 struct d3d_query *query = impl_from_ID3D10Query(iface);
310 HRESULT hr;
312 TRACE("iface %p.\n", iface);
314 wined3d_mutex_lock();
315 if (FAILED(hr = wined3d_query_issue(query->wined3d_query, WINED3DISSUE_END)))
316 ERR("Failed to issue query, hr %#x.\n", hr);
317 wined3d_mutex_unlock();
320 static HRESULT STDMETHODCALLTYPE d3d10_query_GetData(ID3D10Query *iface, void *data, UINT data_size, UINT flags)
322 struct d3d_query *query = impl_from_ID3D10Query(iface);
323 D3D11_QUERY_DATA_PIPELINE_STATISTICS d3d11_data;
324 void *d3d10_data_pointer = NULL;
325 unsigned int wined3d_flags;
326 HRESULT hr;
328 TRACE("iface %p, data %p, data_size %u, flags %#x.\n", iface, data, data_size, flags);
330 if (!data && data_size)
331 return E_INVALIDARG;
333 if (query->desc.Query == D3D11_QUERY_PIPELINE_STATISTICS
334 && data_size == sizeof(D3D10_QUERY_DATA_PIPELINE_STATISTICS))
336 data_size = sizeof(D3D11_QUERY_DATA_PIPELINE_STATISTICS);
337 if (data)
339 d3d10_data_pointer = data;
340 data = &d3d11_data;
344 wined3d_flags = wined3d_getdata_flags_from_d3d11_async_getdata_flags(flags);
346 wined3d_mutex_lock();
347 if (!data_size || wined3d_query_get_data_size(query->wined3d_query) == data_size)
349 hr = wined3d_query_get_data(query->wined3d_query, data, data_size, wined3d_flags);
350 if (hr == WINED3DERR_INVALIDCALL)
351 hr = DXGI_ERROR_INVALID_CALL;
353 else
355 WARN("Invalid data size %u.\n", data_size);
356 hr = E_INVALIDARG;
358 wined3d_mutex_unlock();
360 if (d3d10_data_pointer && hr == S_OK)
361 memcpy(d3d10_data_pointer, data, sizeof(D3D10_QUERY_DATA_PIPELINE_STATISTICS));
363 return hr;
366 static UINT STDMETHODCALLTYPE d3d10_query_GetDataSize(ID3D10Query *iface)
368 struct d3d_query *query = impl_from_ID3D10Query(iface);
369 unsigned int data_size;
371 TRACE("iface %p.\n", iface);
373 wined3d_mutex_lock();
374 data_size = wined3d_query_get_data_size(query->wined3d_query);
375 wined3d_mutex_unlock();
377 if (query->desc.Query == D3D11_QUERY_PIPELINE_STATISTICS)
378 data_size = sizeof(D3D10_QUERY_DATA_PIPELINE_STATISTICS);
380 return data_size;
383 /* ID3D10Query methods */
385 static void STDMETHODCALLTYPE d3d10_query_GetDesc(ID3D10Query *iface, D3D10_QUERY_DESC *desc)
387 struct d3d_query *query = impl_from_ID3D10Query(iface);
389 TRACE("iface %p, desc %p.\n", iface, desc);
391 memcpy(desc, &query->desc, sizeof(*desc));
394 static const struct ID3D10QueryVtbl d3d10_query_vtbl =
396 /* IUnknown methods */
397 d3d10_query_QueryInterface,
398 d3d10_query_AddRef,
399 d3d10_query_Release,
400 /* ID3D10DeviceChild methods */
401 d3d10_query_GetDevice,
402 d3d10_query_GetPrivateData,
403 d3d10_query_SetPrivateData,
404 d3d10_query_SetPrivateDataInterface,
405 /* ID3D10Asynchronous methods */
406 d3d10_query_Begin,
407 d3d10_query_End,
408 d3d10_query_GetData,
409 d3d10_query_GetDataSize,
410 /* ID3D10Query methods */
411 d3d10_query_GetDesc,
414 struct d3d_query *unsafe_impl_from_ID3D10Query(ID3D10Query *iface)
416 if (!iface)
417 return NULL;
418 assert(iface->lpVtbl == &d3d10_query_vtbl);
419 return CONTAINING_RECORD(iface, struct d3d_query, ID3D10Query_iface);
422 static HRESULT d3d_query_init(struct d3d_query *query, struct d3d_device *device,
423 const D3D11_QUERY_DESC *desc, BOOL predicate)
425 HRESULT hr;
427 static const enum wined3d_query_type query_type_map[] =
429 /* D3D11_QUERY_EVENT */ WINED3D_QUERY_TYPE_EVENT,
430 /* D3D11_QUERY_OCCLUSION */ WINED3D_QUERY_TYPE_OCCLUSION,
431 /* D3D11_QUERY_TIMESTAMP */ WINED3D_QUERY_TYPE_TIMESTAMP,
432 /* D3D11_QUERY_TIMESTAMP_DISJOINT */ WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT,
433 /* D3D11_QUERY_PIPELINE_STATISTICS */ WINED3D_QUERY_TYPE_PIPELINE_STATISTICS,
434 /* D3D11_QUERY_OCCLUSION_PREDICATE */ WINED3D_QUERY_TYPE_OCCLUSION,
435 /* D3D11_QUERY_SO_STATISTICS */ WINED3D_QUERY_TYPE_SO_STATISTICS,
436 /* D3D11_QUERY_SO_OVERFLOW_PREDICATE */ WINED3D_QUERY_TYPE_SO_OVERFLOW,
437 /* D3D11_QUERY_SO_STATISTICS_STREAM0 */ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0,
438 /* D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0 */ WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM0,
439 /* D3D11_QUERY_SO_STATISTICS_STREAM1 */ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1,
440 /* D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1 */ WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM1,
441 /* D3D11_QUERY_SO_STATISTICS_STREAM2 */ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2,
442 /* D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2 */ WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM2,
443 /* D3D11_QUERY_SO_STATISTICS_STREAM3 */ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3,
444 /* D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3 */ WINED3D_QUERY_TYPE_SO_OVERFLOW_STREAM3,
447 if (desc->Query >= ARRAY_SIZE(query_type_map))
449 FIXME("Unhandled query type %#x.\n", desc->Query);
450 return E_INVALIDARG;
453 if (desc->MiscFlags)
454 FIXME("Ignoring MiscFlags %#x.\n", desc->MiscFlags);
456 query->ID3D11Query_iface.lpVtbl = &d3d11_query_vtbl;
457 query->ID3D10Query_iface.lpVtbl = &d3d10_query_vtbl;
458 query->refcount = 1;
460 query->desc = *desc;
462 wined3d_mutex_lock();
463 wined3d_private_store_init(&query->private_store);
465 if (FAILED(hr = wined3d_query_create(device->wined3d_device, query_type_map[desc->Query],
466 query, &d3d_query_wined3d_parent_ops, &query->wined3d_query)))
468 WARN("Failed to create wined3d query, hr %#x.\n", hr);
469 wined3d_private_store_cleanup(&query->private_store);
470 wined3d_mutex_unlock();
471 return hr;
473 wined3d_mutex_unlock();
475 query->predicate = predicate;
476 query->device = &device->ID3D11Device_iface;
477 ID3D11Device_AddRef(query->device);
479 return S_OK;
482 HRESULT d3d_query_create(struct d3d_device *device, const D3D11_QUERY_DESC *desc, BOOL predicate,
483 struct d3d_query **query)
485 struct d3d_query *object;
486 BOOL is_predicate_type;
487 HRESULT hr;
489 if (!desc)
490 return E_INVALIDARG;
492 is_predicate_type = desc->Query == D3D11_QUERY_OCCLUSION_PREDICATE
493 || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE
494 || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0
495 || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1
496 || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2
497 || desc->Query == D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3;
499 if (!is_predicate_type && predicate)
501 WARN("Query type %u is not a predicate.\n", desc->Query);
502 return E_INVALIDARG;
505 if (is_predicate_type)
506 predicate = TRUE;
508 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
509 return E_OUTOFMEMORY;
511 if (FAILED(hr = d3d_query_init(object, device, desc, predicate)))
513 WARN("Failed to initialize predicate, hr %#x.\n", hr);
514 HeapFree(GetProcessHeap(), 0, object);
515 return hr;
518 TRACE("Created query %p.\n", object);
519 *query = object;
521 return S_OK;