ReactOS 0.4.17-dev-966-gf06eace
query.c
Go to the documentation of this file.
1/*
2 * Copyright 2005 Oliver Stieber
3 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
4 * Copyright 2009-2010 Henri Verbeet for CodeWeavers.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "wined3d_private.h"
22#include "wined3d_gl.h"
23#include "wined3d_vk.h"
24
26
28{
29 /* map[0] != map[1]: exact values do not have any significance. */
30 query->map_ptr[0] = 0;
31 query->map_ptr[1] = ~(UINT64)0;
32}
33
35{
36 return query->map_ptr[0] == query->map_ptr[1];
37}
38
40{
42 const struct wined3d_gl_info *gl_info = context_gl->gl_info;
43 GLuint buffer_object;
44
45 GL_EXTCALL(glGenBuffers(1, &buffer_object));
46 GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, buffer_object));
47 GL_EXTCALL(glBufferStorage(GL_QUERY_BUFFER, sizeof(query->map_ptr[0]) * 2, NULL, map_flags));
48 query->map_ptr = GL_EXTCALL(glMapBufferRange(GL_QUERY_BUFFER, 0, sizeof(query->map_ptr[0]) * 2, map_flags));
49 GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, 0));
50 checkGLcall("query buffer object creation");
51
53 query->buffer_object = buffer_object;
54}
55
57{
58 const struct wined3d_gl_info *gl_info = context_gl->gl_info;
59
60 GL_EXTCALL(glDeleteBuffers(1, &query->buffer_object));
61 checkGLcall("query buffer object destruction");
62
63 query->buffer_object = 0;
64 query->map_ptr = NULL;
65}
66
67/* From ARB_occlusion_query: "Querying the state for a given occlusion query
68 * forces that occlusion query to complete within a finite amount of time."
69 * In practice, that means drivers flush when retrieving
70 * GL_QUERY_RESULT_AVAILABLE, which can be undesirable when applications use a
71 * significant number of queries. Using a persistently mapped query buffer
72 * object allows us to avoid these implicit flushes. An additional benefit is
73 * that it allows us to poll the query status from the application-thread
74 * instead of from the csmt-thread. */
76 struct wined3d_query *query, GLuint id)
77{
78 const struct wined3d_gl_info *gl_info = context_gl->gl_info;
79 GLsync tmp_sync;
80
82 return FALSE;
83 /* Don't use query buffers without CSMT, mainly for simplicity. */
84 if (!context_gl->c.device->cs->thread)
85 return FALSE;
86
87 if (query->buffer_object)
88 {
89 /* If there's still a query result in-flight for the existing buffer
90 * object (i.e., the query was restarted before we received its
91 * result), we can't reuse the existing buffer object. */
94 else
96 }
97
98 if (!query->buffer_object)
100
101 GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, query->buffer_object));
102 /* Read the same value twice. We know we have the result if map_ptr[0] == map_ptr[1]. */
103 GL_EXTCALL(glGetQueryObjectui64v(id, GL_QUERY_RESULT, (void *)0));
104 GL_EXTCALL(glGetQueryObjectui64v(id, GL_QUERY_RESULT, (void *)sizeof(query->map_ptr[0])));
105 GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, 0));
106 checkGLcall("queue query result");
107
108 /* ARB_buffer_storage requires the client to call FenceSync with
109 * SYNC_GPU_COMMANDS_COMPLETE after the server does a write. This behavior
110 * is not enforced by Mesa.
111 */
112 tmp_sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
113 GL_EXTCALL(glDeleteSync(tmp_sync));
114 checkGLcall("query buffer sync");
115
116 return TRUE;
117}
118
119static UINT64 get_query_result64(GLuint id, const struct wined3d_gl_info *gl_info)
120{
121 if (gl_info->supported[ARB_TIMER_QUERY])
122 {
124 GL_EXTCALL(glGetQueryObjectui64v(id, GL_QUERY_RESULT, &result));
125 return result;
126 }
127 else
128 {
130 GL_EXTCALL(glGetQueryObjectuiv(id, GL_QUERY_RESULT, &result));
131 return result;
132 }
133}
134
136 enum wined3d_query_type type, const void *data, DWORD data_size,
137 const struct wined3d_query_ops *query_ops, void *parent, const struct wined3d_parent_ops *parent_ops)
138{
139 query->ref = 1;
140 query->parent = parent;
141 query->parent_ops = parent_ops;
142 query->device = device;
143 query->state = QUERY_CREATED;
144 query->type = type;
145 query->data = data;
146 query->data_size = data_size;
147 query->query_ops = query_ops;
148 query->poll_in_cs = !!device->cs->thread;
149 list_init(&query->poll_list_entry);
150}
151
153{
155}
156
158{
160}
161
163{
165}
166
168{
170}
171
173 struct wined3d_query *query)
174{
176}
177
180{
181 const struct wined3d_gl_info *gl_info;
182 struct wined3d_context_gl *context_gl;
184 BOOL fence_result;
185
186 TRACE("fence %p, device %p, flags %#x.\n", fence, device, flags);
187
188 if (!fence->context_gl)
189 {
190 TRACE("Fence not issued.\n");
192 }
193
194 if (!(context_gl = wined3d_context_gl_reacquire(fence->context_gl)))
195 {
196 if (!fence->context_gl->gl_info->supported[ARB_SYNC])
197 {
198 WARN("Fence tested from wrong thread.\n");
200 }
202 }
203 gl_info = context_gl->gl_info;
204
205 if (gl_info->supported[ARB_SYNC])
206 {
207 GLenum gl_ret = GL_EXTCALL(glClientWaitSync(fence->object.sync,
209 checkGLcall("glClientWaitSync");
210
211 switch (gl_ret)
212 {
216 break;
217
220 break;
221
222 case GL_WAIT_FAILED:
223 default:
224 ERR("glClientWaitSync returned %#x.\n", gl_ret);
226 }
227 }
228 else if (gl_info->supported[APPLE_FENCE])
229 {
230 fence_result = GL_EXTCALL(glTestFenceAPPLE(fence->object.id));
231 checkGLcall("glTestFenceAPPLE");
232 if (fence_result)
234 else
236 }
237 else if (gl_info->supported[NV_FENCE])
238 {
239 fence_result = GL_EXTCALL(glTestFenceNV(fence->object.id));
240 checkGLcall("glTestFenceNV");
241 if (fence_result)
243 else
245 }
246 else
247 {
248 ERR("Fence created despite lack of GL support.\n");
250 }
251
252 context_release(&context_gl->c);
253 return ret;
254}
255
257 struct wined3d_device *device)
258{
259 const struct wined3d_gl_info *gl_info;
260 struct wined3d_context_gl *context_gl;
262
263 TRACE("fence %p, device %p.\n", fence, device);
264
265 if (!fence->context_gl)
266 {
267 TRACE("Fence not issued.\n");
269 }
270 gl_info = fence->context_gl->gl_info;
271
272 if (!(context_gl = wined3d_context_gl_reacquire(fence->context_gl)))
273 {
274 /* A glFinish does not reliably wait for draws in other contexts. The caller has
275 * to find its own way to cope with the thread switch
276 */
277 if (!gl_info->supported[ARB_SYNC])
278 {
279 WARN("Fence finished from wrong thread.\n");
281 }
283 }
284 gl_info = context_gl->gl_info;
285
286 if (gl_info->supported[ARB_SYNC])
287 {
288 /* Timeouts near 0xffffffffffffffff may immediately return GL_TIMEOUT_EXPIRED,
289 * possibly because macOS internally adds some slop to the timer. To avoid this,
290 * we use a large number that isn't near the point of overflow (macOS 10.12.5).
291 */
292 GLenum gl_ret = GL_EXTCALL(glClientWaitSync(fence->object.sync,
294 checkGLcall("glClientWaitSync");
295
296 switch (gl_ret)
297 {
301 break;
302
303 /* We don't expect a timeout for a ~292 year wait */
304 default:
305 ERR("glClientWaitSync returned %#x.\n", gl_ret);
307 }
308 }
309 else if (gl_info->supported[APPLE_FENCE])
310 {
311 GL_EXTCALL(glFinishFenceAPPLE(fence->object.id));
312 checkGLcall("glFinishFenceAPPLE");
314 }
315 else if (gl_info->supported[NV_FENCE])
316 {
317 GL_EXTCALL(glFinishFenceNV(fence->object.id));
318 checkGLcall("glFinishFenceNV");
320 }
321 else
322 {
323 ERR("Fence created without GL support.\n");
325 }
326
327 context_release(&context_gl->c);
328 return ret;
329}
330
332{
333 struct wined3d_context_gl *context_gl = NULL;
334 const struct wined3d_gl_info *gl_info;
335
336 if (fence->context_gl && !(context_gl = wined3d_context_gl_reacquire(fence->context_gl))
337 && !fence->context_gl->gl_info->supported[ARB_SYNC])
339 if (!context_gl)
341 gl_info = context_gl->gl_info;
342 if (!fence->context_gl)
343 wined3d_context_gl_alloc_fence(context_gl, fence);
344
345 if (gl_info->supported[ARB_SYNC])
346 {
347 if (fence->object.sync)
348 GL_EXTCALL(glDeleteSync(fence->object.sync));
349 checkGLcall("glDeleteSync");
350 fence->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
351 checkGLcall("glFenceSync");
352 }
353 else if (gl_info->supported[APPLE_FENCE])
354 {
355 GL_EXTCALL(glSetFenceAPPLE(fence->object.id));
356 checkGLcall("glSetFenceAPPLE");
357 }
358 else if (gl_info->supported[NV_FENCE])
359 {
360 GL_EXTCALL(glSetFenceNV(fence->object.id, GL_ALL_COMPLETED_NV));
361 checkGLcall("glSetFenceNV");
362 }
363
364 context_release(&context_gl->c);
365}
366
367static void wined3d_fence_free(struct wined3d_fence *fence)
368{
369 if (fence->context_gl)
371}
372
374{
375 wined3d_fence_free(fence);
376 free(fence);
377}
378
379static HRESULT wined3d_fence_init(struct wined3d_fence *fence, const struct wined3d_gl_info *gl_info)
380{
381 if (!wined3d_fence_supported(gl_info))
382 {
383 WARN("Fences not supported.\n");
385 }
386
387 return WINED3D_OK;
388}
389
391{
392 const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl(device->adapter)->gl_info;
393 struct wined3d_fence *object;
394 HRESULT hr;
395
396 TRACE("device %p, fence %p.\n", device, fence);
397
398 if (!(object = calloc(1, sizeof(*object))))
399 return E_OUTOFMEMORY;
400
401 if (FAILED(hr = wined3d_fence_init(object, gl_info)))
402 {
403 free(object);
404 return hr;
405 }
406
407 TRACE("Created fence %p.\n", object);
408 *fence = object;
409
410 return WINED3D_OK;
411}
412
414{
415 unsigned int refcount = InterlockedIncrement(&query->ref);
416
417 TRACE("%p increasing refcount to %u.\n", query, refcount);
418
419 return refcount;
420}
421
422static void wined3d_query_destroy_object(void *object)
423{
424 struct wined3d_query *query = object;
425
426 TRACE("query %p.\n", query);
427
428 if (!list_empty(&query->poll_list_entry))
429 list_remove(&query->poll_list_entry);
430}
431
433{
434 unsigned int refcount = InterlockedDecrement(&query->ref);
435
436 TRACE("%p decreasing refcount to %u.\n", query, refcount);
437
438 if (!refcount)
439 {
440 struct wined3d_device *device = query->device;
441
443 query->parent_ops->wined3d_object_destroyed(query->parent);
445 device->adapter->adapter_ops->adapter_destroy_query(query);
447 }
448
449 return refcount;
450}
451
453 void *data, UINT data_size, uint32_t flags)
454{
455 TRACE("query %p, data %p, data_size %u, flags %#x.\n",
456 query, data, data_size, flags);
457
458 if (query->state == QUERY_BUILDING)
459 {
460 WARN("Query is building, returning S_FALSE.\n");
461 return S_FALSE;
462 }
463
464 if (query->state == QUERY_CREATED)
465 {
466 WARN("Query wasn't started yet.\n");
468 }
469
470 if (query->counter_main != query->counter_retrieved
471 || (query->buffer_object && !wined3d_query_buffer_is_valid(query)))
472 {
473 if (flags & WINED3DGETDATA_FLUSH && !query->device->cs->queries_flushed)
474 query->device->cs->c.ops->flush(&query->device->cs->c);
475 return S_FALSE;
476 }
477 else if (!query->poll_in_cs && !query->query_ops->query_poll(query, flags))
478 {
479 return S_FALSE;
480 }
481
482 if (query->buffer_object)
483 query->data = query->map_ptr;
484
485 if (data)
486 memcpy(data, query->data, min(data_size, query->data_size));
487
488 return S_OK;
489}
490
492{
493 TRACE("query %p.\n", query);
494
495 return query->data_size;
496}
497
499{
500 TRACE("query %p, flags %#x.\n", query, flags);
501
503
504 return WINED3D_OK;
505}
506
508{
510 const struct wined3d_gl_info *gl_info;
511 struct wined3d_context_gl *context_gl;
513
514 TRACE("query %p, flags %#x.\n", query, flags);
515
516 if (!(context_gl = wined3d_context_gl_reacquire(oq->context_gl)))
517 {
518 FIXME("%p Wrong thread, returning 1.\n", query);
519 oq->samples = 1;
520 return TRUE;
521 }
522 gl_info = context_gl->gl_info;
523
524 GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available));
525 TRACE("Available %#x.\n", available);
526
527 if (available)
528 {
530 TRACE("Returning 0x%s samples.\n", wine_dbgstr_longlong(oq->samples));
531 }
532
533 checkGLcall("poll occlusion query");
534 context_release(&context_gl->c);
535
536 return available;
537}
538
540{
543
544 TRACE("query %p, flags %#x.\n", query, flags);
545
546 ret = wined3d_fence_test(&event_query->fence, query->device, flags);
547 switch (ret)
548 {
549 case WINED3D_FENCE_OK:
551 return event_query->signalled = TRUE;
552
554 return event_query->signalled = FALSE;
555
557 FIXME("(%p) Wrong thread, reporting GPU idle.\n", query);
558 return event_query->signalled = TRUE;
559
561 ERR("The GL event query failed.\n");
562 return event_query->signalled = TRUE;
563
564 default:
565 ERR("Unexpected wined3d_event_query_test result %#x.\n", ret);
566 return event_query->signalled = TRUE;
567 }
568}
569
571{
572 TRACE("query %p.\n", query);
573
574 return query->parent;
575}
576
578{
579 TRACE("query %p.\n", query);
580
581 return query->type;
582}
583
585{
586 TRACE("query %p, flags %#x.\n", query, flags);
587
589 {
591
592 wined3d_fence_issue(&event_query->fence, query->device);
593 return TRUE;
594 }
595 else if (flags & WINED3DISSUE_BEGIN)
596 {
597 /* Started implicitly at query creation. */
598 ERR("Event query issued with START flag - what to do?\n");
599 }
600
601 return FALSE;
602}
603
605{
607 struct wined3d_device *device = query->device;
608 const struct wined3d_gl_info *gl_info;
609 struct wined3d_context_gl *context_gl;
610 BOOL poll = FALSE;
611
612 TRACE("query %p, flags %#x.\n", query, flags);
613
614 /* This is allowed according to MSDN and our tests. Reset the query and
615 * restart. */
617 {
618 if (oq->started)
619 {
620 if ((context_gl = wined3d_context_gl_reacquire(oq->context_gl)))
621 {
622 gl_info = context_gl->gl_info;
623 GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
624 checkGLcall("glEndQuery()");
625 }
626 else
627 {
628 FIXME("Wrong thread, can't restart query.\n");
632 }
633 }
634 else
635 {
636 if (oq->context_gl)
640 }
641 gl_info = context_gl->gl_info;
642
643 GL_EXTCALL(glBeginQuery(GL_SAMPLES_PASSED, oq->id));
644 checkGLcall("glBeginQuery()");
645
646 context_release(&context_gl->c);
647 oq->started = TRUE;
648 }
650 {
651 /* MSDN says END on a non-building occlusion query returns an error,
652 * but our tests show that it returns OK. But OpenGL doesn't like it,
653 * so avoid generating an error. */
654 if (oq->started)
655 {
656 if ((context_gl = wined3d_context_gl_reacquire(oq->context_gl)))
657 {
658 gl_info = context_gl->gl_info;
659 GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
660 checkGLcall("glEndQuery()");
662
663 context_release(&context_gl->c);
664 poll = TRUE;
665 }
666 else
667 {
668 FIXME("Wrong thread, can't end query.\n");
669 }
670 }
671 oq->started = FALSE;
672 }
673
674 return poll;
675}
676
678{
680 const struct wined3d_gl_info *gl_info;
681 struct wined3d_context_gl *context_gl;
684
685 TRACE("query %p, flags %#x.\n", query, flags);
686
687 if (!(context_gl = wined3d_context_gl_reacquire(tq->context_gl)))
688 {
689 FIXME("%p Wrong thread, returning 1.\n", query);
690 tq->timestamp = 1;
691 return TRUE;
692 }
693 gl_info = context_gl->gl_info;
694
695 GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available));
696 checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)");
697 TRACE("available %#x.\n", available);
698
699 if (available)
700 {
701 GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, &timestamp));
702 checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)");
703 TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp));
704 tq->timestamp = timestamp;
705 }
706
707 context_release(&context_gl->c);
708
709 return available;
710}
711
713{
715 const struct wined3d_gl_info *gl_info;
716 struct wined3d_context_gl *context_gl;
717
718 TRACE("query %p, flags %#x.\n", query, flags);
719
721 {
722 WARN("Ignoring WINED3DISSUE_BEGIN with a TIMESTAMP query.\n");
723 }
725 {
726 if (tq->context_gl)
728 context_gl = wined3d_context_gl(context_acquire(query->device, NULL, 0));
729 gl_info = context_gl->gl_info;
731 GL_EXTCALL(glQueryCounter(tq->id, GL_TIMESTAMP));
732 checkGLcall("glQueryCounter()");
733 context_release(&context_gl->c);
734
735 return TRUE;
736 }
737
738 return FALSE;
739}
740
742{
743 TRACE("query %p, flags %#x.\n", query, flags);
744
745 return TRUE;
746}
747
749{
750 TRACE("query %p, flags %#x.\n", query, flags);
751
752 return FALSE;
753}
754
756{
758 GLuint written_available, generated_available;
759 const struct wined3d_gl_info *gl_info;
760 struct wined3d_context_gl *context_gl;
761
762 TRACE("query %p, flags %#x.\n", query, flags);
763
764 if (!(context_gl = wined3d_context_gl_reacquire(pq->context_gl)))
765 {
766 FIXME("%p Wrong thread, returning 0 primitives.\n", query);
767 memset(&pq->statistics, 0, sizeof(pq->statistics));
768 return TRUE;
769 }
770 gl_info = context_gl->gl_info;
771
772 GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.written,
773 GL_QUERY_RESULT_AVAILABLE, &written_available));
774 GL_EXTCALL(glGetQueryObjectuiv(pq->u.query.generated,
775 GL_QUERY_RESULT_AVAILABLE, &generated_available));
776 TRACE("Available %#x, %#x.\n", written_available, generated_available);
777
778 if (written_available && generated_available)
779 {
780 pq->statistics.primitives_written = get_query_result64(pq->u.query.written, gl_info);
781 pq->statistics.primitives_generated = get_query_result64(pq->u.query.generated, gl_info);
782 TRACE("Returning %s, %s primitives.\n",
783 wine_dbgstr_longlong(pq->statistics.primitives_written),
784 wine_dbgstr_longlong(pq->statistics.primitives_generated));
785 }
786
787 checkGLcall("poll SO statistics query");
788 context_release(&context_gl->c);
789
790 return written_available && generated_available;
791}
792
794 struct wined3d_context_gl *context_gl)
795{
796 const struct wined3d_gl_info *gl_info = context_gl->gl_info;
797
799 {
800 GL_EXTCALL(glEndQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query->stream_idx));
801 GL_EXTCALL(glEndQueryIndexed(GL_PRIMITIVES_GENERATED, query->stream_idx));
802 }
803 else
804 {
807 }
808 checkGLcall("end query");
809}
810
812{
814 struct wined3d_device *device = query->device;
815 const struct wined3d_gl_info *gl_info;
816 struct wined3d_context_gl *context_gl;
817 BOOL poll = FALSE;
818
819 TRACE("query %p, flags %#x.\n", query, flags);
820
822 {
823 if (pq->started)
824 {
825 if ((context_gl = wined3d_context_gl_reacquire(pq->context_gl)))
826 {
827 wined3d_so_statistics_query_end(pq, context_gl);
828 }
829 else
830 {
831 FIXME("Wrong thread, can't restart query.\n");
835 }
836 }
837 else
838 {
839 if (pq->context_gl)
843 }
844 gl_info = context_gl->gl_info;
845
846 if (gl_info->supported[ARB_TRANSFORM_FEEDBACK3])
847 {
849 pq->stream_idx, pq->u.query.written));
850 GL_EXTCALL(glBeginQueryIndexed(GL_PRIMITIVES_GENERATED,
851 pq->stream_idx, pq->u.query.generated));
852 }
853 else
854 {
856 pq->u.query.written));
858 pq->u.query.generated));
859 }
860 checkGLcall("begin query");
861
862 context_release(&context_gl->c);
863 pq->started = TRUE;
864 }
866 {
867 if (pq->started)
868 {
869 if ((context_gl = wined3d_context_gl_reacquire(pq->context_gl)))
870 {
871 wined3d_so_statistics_query_end(pq, context_gl);
872
873 context_release(&context_gl->c);
874 poll = TRUE;
875 }
876 else
877 {
878 FIXME("Wrong thread, can't end query.\n");
879 }
880 }
881 pq->started = FALSE;
882 }
883
884 return poll;
885}
886
888{
890 const struct wined3d_gl_info *gl_info;
891 struct wined3d_context_gl *context_gl;
893 int i;
894
895 TRACE("query %p, flags %#x.\n", query, flags);
896
897 if (!(context_gl = wined3d_context_gl_reacquire(pq->context_gl)))
898 {
899 FIXME("%p Wrong thread.\n", query);
900 memset(&pq->statistics, 0, sizeof(pq->statistics));
901 return TRUE;
902 }
903 gl_info = context_gl->gl_info;
904
905 for (i = 0; i < ARRAY_SIZE(pq->u.id); ++i)
906 {
907 GL_EXTCALL(glGetQueryObjectuiv(pq->u.id[i], GL_QUERY_RESULT_AVAILABLE, &available));
908 if (!available)
909 break;
910 }
911
912 if (available)
913 {
914 pq->statistics.vertices_submitted = get_query_result64(pq->u.query.vertices, gl_info);
915 pq->statistics.primitives_submitted = get_query_result64(pq->u.query.primitives, gl_info);
916 pq->statistics.vs_invocations = get_query_result64(pq->u.query.vertex_shader, gl_info);
917 pq->statistics.hs_invocations = get_query_result64(pq->u.query.tess_control_shader, gl_info);
918 pq->statistics.ds_invocations = get_query_result64(pq->u.query.tess_eval_shader, gl_info);
919 pq->statistics.gs_invocations = get_query_result64(pq->u.query.geometry_shader, gl_info);
920 pq->statistics.gs_primitives = get_query_result64(pq->u.query.geometry_primitives, gl_info);
921 pq->statistics.ps_invocations = get_query_result64(pq->u.query.fragment_shader, gl_info);
922 pq->statistics.cs_invocations = get_query_result64(pq->u.query.compute_shader, gl_info);
923 pq->statistics.clipping_input_primitives = get_query_result64(pq->u.query.clipping_input, gl_info);
924 pq->statistics.clipping_output_primitives = get_query_result64(pq->u.query.clipping_output, gl_info);
925 }
926
927 checkGLcall("poll pipeline statistics query");
928 context_release(&context_gl->c);
929 return available;
930}
931
933 struct wined3d_context_gl *context_gl)
934{
935 const struct wined3d_gl_info *gl_info = context_gl->gl_info;
936
948 checkGLcall("end query");
949}
950
952{
954 struct wined3d_device *device = query->device;
955 const struct wined3d_gl_info *gl_info;
956 struct wined3d_context_gl *context_gl;
957 BOOL poll = FALSE;
958
959 TRACE("query %p, flags %#x.\n", query, flags);
960
962 {
963 if (pq->started)
964 {
965 if ((context_gl = wined3d_context_gl_reacquire(pq->context_gl)))
966 {
968 }
969 else
970 {
971 FIXME("Wrong thread, can't restart query.\n");
975 }
976 }
977 else
978 {
979 if (pq->context_gl)
983 }
984 gl_info = context_gl->gl_info;
985
986 GL_EXTCALL(glBeginQuery(GL_VERTICES_SUBMITTED_ARB, pq->u.query.vertices));
987 GL_EXTCALL(glBeginQuery(GL_PRIMITIVES_SUBMITTED_ARB, pq->u.query.primitives));
988 GL_EXTCALL(glBeginQuery(GL_VERTEX_SHADER_INVOCATIONS_ARB, pq->u.query.vertex_shader));
989 GL_EXTCALL(glBeginQuery(GL_TESS_CONTROL_SHADER_PATCHES_ARB, pq->u.query.tess_control_shader));
990 GL_EXTCALL(glBeginQuery(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB, pq->u.query.tess_eval_shader));
991 GL_EXTCALL(glBeginQuery(GL_GEOMETRY_SHADER_INVOCATIONS, pq->u.query.geometry_shader));
992 GL_EXTCALL(glBeginQuery(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB, pq->u.query.geometry_primitives));
993 GL_EXTCALL(glBeginQuery(GL_FRAGMENT_SHADER_INVOCATIONS_ARB, pq->u.query.fragment_shader));
994 GL_EXTCALL(glBeginQuery(GL_COMPUTE_SHADER_INVOCATIONS_ARB, pq->u.query.compute_shader));
995 GL_EXTCALL(glBeginQuery(GL_CLIPPING_INPUT_PRIMITIVES_ARB, pq->u.query.clipping_input));
996 GL_EXTCALL(glBeginQuery(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB, pq->u.query.clipping_output));
997 checkGLcall("begin query");
998
999 context_release(&context_gl->c);
1000 pq->started = TRUE;
1001 }
1002 if (flags & WINED3DISSUE_END)
1003 {
1004 if (pq->started)
1005 {
1006 if ((context_gl = wined3d_context_gl_reacquire(pq->context_gl)))
1007 {
1009 context_release(&context_gl->c);
1010 poll = TRUE;
1011 }
1012 else
1013 {
1014 FIXME("Wrong thread, can't end query.\n");
1015 }
1016 }
1017 pq->started = FALSE;
1018 }
1019
1020 return poll;
1021}
1022
1024{
1026
1027 wined3d_fence_free(&event_query->fence);
1028 free(event_query);
1029}
1030
1032{
1036};
1037
1039 enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
1040 struct wined3d_query **query)
1041{
1042 const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl(device->adapter)->gl_info;
1044 HRESULT hr;
1045
1046 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1047 device, type, parent, parent_ops, query);
1048
1049 if (!(object = calloc(1, sizeof(*object))))
1050 return E_OUTOFMEMORY;
1051
1052 if (FAILED(hr = wined3d_fence_init(&object->fence, gl_info)))
1053 {
1054 WARN("Event queries not supported.\n");
1055 free(object);
1056 return hr;
1057 }
1058
1059 wined3d_query_init(&object->query, device, type, &object->signalled,
1060 sizeof(object->signalled), &event_query_ops, parent, parent_ops);
1061
1062 TRACE("Created query %p.\n", object);
1063 *query = &object->query;
1064
1065 return WINED3D_OK;
1066}
1067
1069{
1071
1072 if (oq->context_gl)
1074 free(oq);
1075}
1076
1078{
1082};
1083
1085 enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
1086 struct wined3d_query **query)
1087{
1088 const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl(device->adapter)->gl_info;
1090
1091 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1092 device, type, parent, parent_ops, query);
1093
1094 if (!gl_info->supported[ARB_OCCLUSION_QUERY])
1095 {
1096 WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY.\n");
1098 }
1099
1100 if (!(object = calloc(1, sizeof(*object))))
1101 return E_OUTOFMEMORY;
1102
1103 wined3d_query_init(&object->query, device, type, &object->samples,
1104 sizeof(object->samples), &occlusion_query_ops, parent, parent_ops);
1105
1106 TRACE("Created query %p.\n", object);
1107 *query = &object->query;
1108
1109 return WINED3D_OK;
1110}
1111
1113{
1115
1116 if (tq->context_gl)
1118 free(tq);
1119}
1120
1122{
1126};
1127
1129 enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
1130 struct wined3d_query **query)
1131{
1132 const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl(device->adapter)->gl_info;
1134
1135 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1136 device, type, parent, parent_ops, query);
1137
1138 if (!gl_info->supported[ARB_TIMER_QUERY])
1139 {
1140 WARN("Unsupported in local OpenGL implementation: ARB_TIMER_QUERY.\n");
1142 }
1143
1144 if (!(object = calloc(1, sizeof(*object))))
1145 return E_OUTOFMEMORY;
1146
1147 wined3d_query_init(&object->query, device, type, &object->timestamp,
1148 sizeof(object->timestamp), &timestamp_query_ops, parent, parent_ops);
1149
1150 TRACE("Created query %p.\n", object);
1151 *query = &object->query;
1152
1153 return WINED3D_OK;
1154}
1155
1157{
1158 free(query);
1159}
1160
1162{
1166};
1167
1169 enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
1170 struct wined3d_query **query)
1171{
1172 const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl(device->adapter)->gl_info;
1173 struct wined3d_query *object;
1174
1175 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1177
1178 if (!gl_info->supported[ARB_TIMER_QUERY])
1179 {
1180 WARN("Unsupported in local OpenGL implementation: ARB_TIMER_QUERY.\n");
1182 }
1183
1184 if (!(object = calloc(1, sizeof(*object))))
1185 return E_OUTOFMEMORY;
1186
1188 {
1189 static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE};
1190
1191 wined3d_query_init(object, device, type, &disjoint_data,
1192 sizeof(disjoint_data), &timestamp_disjoint_query_ops, parent, parent_ops);
1193 }
1194 else
1195 {
1196 static const UINT64 freq = 1000 * 1000 * 1000;
1197
1198 wined3d_query_init(object, device, type, &freq,
1199 sizeof(freq), &timestamp_disjoint_query_ops, parent, parent_ops);
1200 }
1201
1202 TRACE("Created query %p.\n", object);
1203 *query = object;
1204
1205 return WINED3D_OK;
1206}
1207
1209{
1211
1212 if (pq->context_gl)
1214 free(pq);
1215}
1216
1218{
1222};
1223
1225 enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
1226 struct wined3d_query **query)
1227{
1228 const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl(device->adapter)->gl_info;
1230 unsigned int stream_idx;
1231
1235 stream_idx = 0;
1236 else
1238
1239 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1240 device, type, parent, parent_ops, query);
1241
1243 {
1244 WARN("OpenGL implementation does not support primitive queries.\n");
1246 }
1248 {
1249 WARN("OpenGL implementation does not support indexed queries.\n");
1251 }
1252
1253 if (!(object = calloc(1, sizeof(*object))))
1254 return E_OUTOFMEMORY;
1255
1256 wined3d_query_init(&object->query, device, type, &object->statistics,
1257 sizeof(object->statistics), &so_statistics_query_ops, parent, parent_ops);
1258 object->stream_idx = stream_idx;
1259
1260 TRACE("Created query %p.\n", object);
1261 *query = &object->query;
1262
1263 return WINED3D_OK;
1264}
1265
1267{
1269 if (pq->context_gl)
1271 free(pq);
1272}
1273
1275{
1279};
1280
1282 enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops,
1283 struct wined3d_query **query)
1284{
1285 const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl(device->adapter)->gl_info;
1287
1288 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1289 device, type, parent, parent_ops, query);
1290
1292 {
1293 WARN("OpenGL implementation does not support pipeline statistics queries.\n");
1295 }
1296
1297 if (!(object = calloc(1, sizeof(*object))))
1298 return E_OUTOFMEMORY;
1299
1300 wined3d_query_init(&object->query, device, type, &object->statistics,
1301 sizeof(object->statistics), &pipeline_query_ops, parent, parent_ops);
1302
1303 TRACE("Created query %p.\n", object);
1304 *query = &object->query;
1305
1306 return WINED3D_OK;
1307}
1308
1310 void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
1311{
1312 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1313 device, type, parent, parent_ops, query);
1314
1315 switch (type)
1316 {
1318 return wined3d_event_query_create(device, type, parent, parent_ops, query);
1319
1321 return wined3d_occlusion_query_create(device, type, parent, parent_ops, query);
1322
1324 return wined3d_timestamp_query_create(device, type, parent, parent_ops, query);
1325
1329
1336
1338 return wined3d_pipeline_query_create(device, type, parent, parent_ops, query);
1339
1340 default:
1341 FIXME("Unhandled query type %#x.\n", type);
1343 }
1344}
1345
1347 struct wined3d_context_vk *context_vk)
1348{
1349 /* Don't reset completed queries right away, as vkCmdResetQueryPool() needs to happen
1350 * outside of a render pass. Queue the query to be reset at the very end of the current
1351 * command buffer instead. */
1352 wined3d_bitmap_set(pool_vk->completed, idx);
1353 if (list_empty(&pool_vk->completed_entry))
1354 list_add_tail(&context_vk->completed_query_pools, &pool_vk->completed_entry);
1355}
1356
1358{
1360 return false;
1361 wined3d_bitmap_set(pool_vk->allocated, *idx);
1362
1363 return true;
1364}
1365
1368{
1369 unsigned int idx, end = start + count;
1370
1371 for (idx = start; idx < end; ++idx)
1373
1374 if (list_empty(&pool_vk->entry))
1375 list_add_tail(pool_vk->free_list, &pool_vk->entry);
1376}
1377
1379{
1380 struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
1381 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
1382
1383 VK_CALL(vkDestroyQueryPool(device_vk->vk_device, pool_vk->vk_query_pool, NULL));
1384 if (pool_vk->vk_event)
1385 VK_CALL(vkDestroyEvent(device_vk->vk_device, pool_vk->vk_event, NULL));
1386 list_remove(&pool_vk->entry);
1387 list_remove(&pool_vk->completed_entry);
1388}
1389
1391 struct wined3d_context_vk *context_vk, enum wined3d_query_type type, struct list *free_pools)
1392{
1393 struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
1394 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
1395 VkQueryPoolCreateInfo pool_info;
1396 VkResult vr;
1397
1398 list_init(&pool_vk->entry);
1399 list_init(&pool_vk->completed_entry);
1400 pool_vk->free_list = free_pools;
1401
1403 pool_info.pNext = NULL;
1404 pool_info.flags = 0;
1406
1407 switch (type)
1408 {
1411 pool_info.pipelineStatistics = 0;
1412 break;
1413
1416 pool_info.pipelineStatistics = 0;
1417 break;
1418
1432 break;
1433
1440 pool_info.pipelineStatistics = 0;
1441 break;
1442
1443 default:
1444 FIXME("Unhandled query type %#x.\n", type);
1445 return false;
1446 }
1447
1448 if ((vr = VK_CALL(vkCreateQueryPool(device_vk->vk_device, &pool_info, NULL, &pool_vk->vk_query_pool))) < 0)
1449 {
1450 ERR("Failed to create Vulkan query pool, vr %s.\n", wined3d_debug_vkresult(vr));
1451 return false;
1452 }
1453
1454 list_add_head(free_pools, &pool_vk->entry);
1455
1456 return true;
1457}
1458
1460 struct wined3d_device_vk *device_vk, const struct wined3d_query_pool_idx_vk *pool_idx)
1461{
1462 const struct wined3d_query_data_pipeline_statistics *ps_tmp;
1463 const struct wined3d_vk_info *vk_info = &device_vk->vk_info;
1465 VkResult vr;
1466 union
1467 {
1468 uint64_t occlusion;
1470 struct wined3d_query_data_pipeline_statistics pipeline_statistics;
1471 struct wined3d_query_data_so_statistics so_statistics;
1472 } tmp, *result;
1473
1474 if (pool_idx->pool_vk->vk_event)
1475 {
1476 /* Check if the pool's initial reset command executed. */
1477 vr = VK_CALL(vkGetEventStatus(device_vk->vk_device,
1478 pool_idx->pool_vk->vk_event));
1479 if (vr == VK_EVENT_RESET)
1480 return false;
1481 else if (vr != VK_EVENT_SET)
1482 {
1483 ERR("Failed to get event status, vr %s\n", wined3d_debug_vkresult(vr));
1484 return false;
1485 }
1486 }
1487
1488 if ((vr = VK_CALL(vkGetQueryPoolResults(device_vk->vk_device, pool_idx->pool_vk->vk_query_pool,
1489 pool_idx->idx, 1, sizeof(tmp), &tmp, sizeof(tmp), VK_QUERY_RESULT_64_BIT))) < 0)
1490 {
1491 ERR("Failed to get query results, vr %s.\n", wined3d_debug_vkresult(vr));
1492 return false;
1493 }
1494
1495 if (vr == VK_NOT_READY)
1496 return false;
1497
1498 result = (void *)query_vk->q.data;
1499 switch (query_vk->q.type)
1500 {
1502 result->occlusion += tmp.occlusion;
1503 break;
1504
1506 result->timestamp = tmp.timestamp;
1507 break;
1508
1510 ps_result = &result->pipeline_statistics;
1511 ps_tmp = &tmp.pipeline_statistics;
1512 ps_result->vertices_submitted += ps_tmp->vertices_submitted;
1513 ps_result->primitives_submitted += ps_tmp->primitives_submitted;
1514 ps_result->vs_invocations += ps_tmp->vs_invocations;
1515 ps_result->gs_invocations += ps_tmp->gs_invocations;
1516 ps_result->gs_primitives += ps_tmp->gs_primitives;
1519 ps_result->ps_invocations += ps_tmp->ps_invocations;
1520 ps_result->hs_invocations += ps_tmp->hs_invocations;
1521 ps_result->ds_invocations += ps_tmp->ds_invocations;
1522 ps_result->cs_invocations += ps_tmp->cs_invocations;
1523 break;
1524
1530 result->so_statistics.primitives_written += tmp.so_statistics.primitives_written;
1531 result->so_statistics.primitives_generated += tmp.so_statistics.primitives_generated;
1532 break;
1533
1534 default:
1535 FIXME("Unhandled query type %#x.\n", query_vk->q.type);
1536 return false;
1537 }
1538
1539 return true;
1540}
1541
1542static void wined3d_query_vk_begin(struct wined3d_query_vk *query_vk,
1543 struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer)
1544{
1545 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
1546 struct wined3d_query_pool_vk *pool_vk;
1547 size_t idx;
1548
1549 pool_vk = query_vk->pool_idx.pool_vk;
1550 idx = query_vk->pool_idx.idx;
1551
1552 if (query_vk->q.type >= WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1
1553 && query_vk->q.type <= WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3)
1554 VK_CALL(vkCmdBeginQueryIndexedEXT(vk_command_buffer, pool_vk->vk_query_pool, idx,
1555 query_vk->control_flags, query_vk->q.type - WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0));
1556 else
1557 VK_CALL(vkCmdBeginQuery(vk_command_buffer, pool_vk->vk_query_pool, idx, query_vk->control_flags));
1558 wined3d_context_vk_reference_query(context_vk, query_vk);
1559}
1560
1561static void wined3d_query_vk_end(struct wined3d_query_vk *query_vk,
1562 struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer)
1563{
1564 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
1565 struct wined3d_query_pool_vk *pool_vk;
1566 size_t idx;
1567
1568 pool_vk = query_vk->pool_idx.pool_vk;
1569 idx = query_vk->pool_idx.idx;
1570
1571 if (query_vk->q.type >= WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1
1572 && query_vk->q.type <= WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3)
1573 VK_CALL(vkCmdEndQueryIndexedEXT(vk_command_buffer, pool_vk->vk_query_pool,
1575 else
1576 VK_CALL(vkCmdEndQuery(vk_command_buffer, pool_vk->vk_query_pool, idx));
1577}
1578
1579void wined3d_query_vk_resume(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk)
1580{
1581 VkCommandBuffer vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer;
1582
1583 wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer);
1585}
1586
1587void wined3d_query_vk_suspend(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk)
1588{
1589 VkCommandBuffer vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer;
1590
1591 wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer);
1592
1593 if (!wined3d_array_reserve((void **)&query_vk->pending, &query_vk->pending_size,
1594 query_vk->pending_count + 1, sizeof(*query_vk->pending)))
1595 {
1596 ERR("Failed to allocate entry.\n");
1597 return;
1598 }
1599
1600 query_vk->pending[query_vk->pending_count++] = query_vk->pool_idx;
1601 query_vk->pool_idx.pool_vk = NULL;
1602 query_vk->flags &= ~WINED3D_QUERY_VK_FLAG_ACTIVE;
1603}
1604
1606{
1607 struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device);
1608 struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
1609 unsigned int i;
1610
1611 memset((void *)query->data, 0, query->data_size);
1612
1613 if (query_vk->pool_idx.pool_vk && !wined3d_query_vk_accumulate_data(query_vk, device_vk, &query_vk->pool_idx))
1614 goto unavailable;
1615
1616 for (i = 0; i < query_vk->pending_count; ++i)
1617 {
1618 if (!wined3d_query_vk_accumulate_data(query_vk, device_vk, &query_vk->pending[i]))
1619 goto unavailable;
1620 }
1621
1622 return TRUE;
1623
1624unavailable:
1625 if ((flags & WINED3DGETDATA_FLUSH) && !query->device->cs->queries_flushed)
1626 query->device->cs->c.ops->flush(&query->device->cs->c);
1627
1628 return FALSE;
1629}
1630
1632 struct wined3d_query_vk *query_vk)
1633{
1634 size_t i;
1635
1636 for (i = 0; i < query_vk->pending_count; ++i)
1637 wined3d_query_pool_vk_mark_complete(query_vk->pending[i].pool_vk, query_vk->pending[i].idx, context_vk);
1638
1639 query_vk->pending_count = 0;
1640}
1641
1643{
1644 struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device);
1645 struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
1646 struct wined3d_context_vk *context_vk;
1647 VkCommandBuffer vk_command_buffer;
1648 bool poll = false;
1649
1650 TRACE("query %p, flags %#x.\n", query, flags);
1651
1653 {
1654 context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
1655
1656 if (query_vk->pending_count)
1657 wined3d_query_vk_remove_pending_queries(context_vk, query_vk);
1658 vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
1659 if (query_vk->flags & WINED3D_QUERY_VK_FLAG_STARTED)
1660 {
1661 if (query_vk->flags & WINED3D_QUERY_VK_FLAG_ACTIVE)
1662 wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer);
1663 list_remove(&query_vk->entry);
1664 }
1665 if (query_vk->pool_idx.pool_vk)
1667 query_vk->pool_idx.idx, context_vk);
1668
1669 if (!wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx))
1670 {
1671 ERR("Failed to allocate new query.\n");
1672 return false;
1673 }
1674
1675 /* A query needs to either begin and end inside a single render pass
1676 * or begin and end outside of a render pass. Occlusion queries, if
1677 * issued outside of a render pass, are queued up and only begun when
1678 * a render pass is started, to avoid interrupting the render pass
1679 * when the query ends. */
1680 if (context_vk->vk_render_pass)
1681 {
1682 wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer);
1683 list_add_head(&context_vk->render_pass_queries, &query_vk->entry);
1685 }
1686 else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION)
1687 {
1688 list_add_head(&context_vk->render_pass_queries, &query_vk->entry);
1690 }
1691 else
1692 {
1693 wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer);
1694 list_add_head(&context_vk->active_queries, &query_vk->entry);
1696 }
1697
1699 context_release(&context_vk->c);
1700 }
1702 {
1703 context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
1704
1705 /* If the query was already ended because the command buffer was
1706 * flushed or the render pass ended, we don't need to end it here. */
1707 if (query_vk->flags & WINED3D_QUERY_VK_FLAG_ACTIVE)
1708 vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
1709
1710 /* wined3d_context_vk_get_command_buffer() might have triggered
1711 * submission of the previous command buffer (due to retired
1712 * resource accumulation or periodic submit).
1713 * This will have suspended the query, and if it's a render pass
1714 * query, it won't have been resumed and therefore shouldn't be ended
1715 * here. Therefore we need to check whether it's active again. */
1716 if (query_vk->flags & WINED3D_QUERY_VK_FLAG_ACTIVE)
1717 {
1718 if (!(query_vk->flags & WINED3D_QUERY_VK_FLAG_RENDER_PASS))
1720 wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer);
1721 }
1722 else if (query_vk->pool_idx.pool_vk)
1723 {
1724 /* It was queued, but never activated. */
1726 query_vk->pool_idx.idx, context_vk);
1727 query_vk->pool_idx.pool_vk = NULL;
1728 }
1729 list_remove(&query_vk->entry);
1730 query_vk->flags = 0;
1731 poll = true;
1732
1733 context_release(&context_vk->c);
1734 }
1735
1736 return poll;
1737}
1738
1740{
1741 struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
1742 struct wined3d_context_vk *context_vk;
1743
1744 if (query_vk->flags & WINED3D_QUERY_VK_FLAG_STARTED)
1745 list_remove(&query_vk->entry);
1746 context_vk = wined3d_context_vk(context_acquire(query_vk->q.device, NULL, 0));
1747 wined3d_query_vk_remove_pending_queries(context_vk, query_vk);
1748 if (query_vk->pool_idx.pool_vk)
1749 wined3d_query_pool_vk_mark_complete(query_vk->pool_idx.pool_vk, query_vk->pool_idx.idx, context_vk);
1750 if (query_vk->vk_event)
1751 wined3d_context_vk_destroy_vk_event(context_vk, query_vk->vk_event, query_vk->command_buffer_id);
1752 context_release(&context_vk->c);
1753 free(query_vk->pending);
1754 free(query_vk);
1755}
1756
1758{
1759 .query_poll = wined3d_query_vk_poll,
1760 .query_issue = wined3d_query_vk_issue,
1761 .query_destroy = wined3d_query_vk_destroy,
1762};
1763
1765{
1766 struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device);
1767 struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
1768 const struct wined3d_vk_info *vk_info = &device_vk->vk_info;
1769 BOOL signalled;
1770
1771 signalled = VK_CALL(vkGetEventStatus(device_vk->vk_device, query_vk->vk_event))
1772 == VK_EVENT_SET;
1773 if (!signalled && (flags & WINED3DGETDATA_FLUSH) && !query->device->cs->queries_flushed)
1774 query->device->cs->c.ops->flush(&query->device->cs->c);
1775 return *(BOOL *)query->data = signalled;
1776}
1777
1779{
1780 struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device);
1781 const struct wined3d_vk_info *vk_info = &device_vk->vk_info;
1782 struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
1783 struct wined3d_context_vk *context_vk;
1784 VkEventCreateInfo create_info;
1785 VkResult vr;
1786
1787 TRACE("query %p, flags %#x.\n", query, flags);
1788
1789 if (flags & WINED3DISSUE_END)
1790 {
1791 context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
1793
1794 if (query_vk->vk_event)
1795 {
1796 if (query_vk->command_buffer_id > context_vk->completed_command_buffer_id)
1797 {
1798 /* Cannot reuse this event, as it may still get signalled by previous usage. */
1799 /* Throw it away and create a new one, but if that happens a lot we may want to pool instead. */
1800 wined3d_context_vk_destroy_vk_event(context_vk, query_vk->vk_event, query_vk->command_buffer_id);
1801 query_vk->vk_event = VK_NULL_HANDLE;
1802 }
1803 else
1804 {
1805 VK_CALL(vkResetEvent(device_vk->vk_device, query_vk->vk_event));
1806 }
1807 }
1808
1809 if (!query_vk->vk_event)
1810 {
1812 create_info.pNext = NULL;
1813 create_info.flags = 0;
1814
1815 vr = VK_CALL(vkCreateEvent(device_vk->vk_device, &create_info, NULL, &query_vk->vk_event));
1816 if (vr != VK_SUCCESS)
1817 {
1818 ERR("Failed to create Vulkan event, vr %s\n", wined3d_debug_vkresult(vr));
1819 context_release(&context_vk->c);
1820 return FALSE;
1821 }
1822 }
1823
1824 wined3d_context_vk_reference_query(context_vk, query_vk);
1827 context_release(&context_vk->c);
1828
1829 return TRUE;
1830 }
1831
1832 return FALSE;
1833}
1834
1836{
1837 .query_poll = wined3d_query_event_vk_poll,
1838 .query_issue = wined3d_query_event_vk_issue,
1839 .query_destroy = wined3d_query_vk_destroy,
1840};
1841
1843{
1844 struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device);
1845 struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
1846 const struct wined3d_vk_info *vk_info;
1847 struct wined3d_context_vk *context_vk;
1848 VkCommandBuffer command_buffer;
1849
1850 TRACE("query %p, flags %#x.\n", query, flags);
1851
1853 TRACE("Ignoring WINED3DISSUE_BEGIN.\n");
1854
1855 if (flags & WINED3DISSUE_END)
1856 {
1857 context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
1858 vk_info = context_vk->vk_info;
1859
1860 command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
1861 if (query_vk->pool_idx.pool_vk)
1862 wined3d_query_pool_vk_mark_complete(query_vk->pool_idx.pool_vk, query_vk->pool_idx.idx, context_vk);
1863 if (!wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx))
1864 {
1865 ERR("Failed to allocate new query.\n");
1866 return FALSE;
1867 }
1869 query_vk->pool_idx.pool_vk->vk_query_pool, query_vk->pool_idx.idx));
1870 wined3d_context_vk_reference_query(context_vk, query_vk);
1871
1872 context_release(&context_vk->c);
1873
1874 return TRUE;
1875 }
1876
1877 return FALSE;
1878}
1879
1881{
1882 .query_poll = wined3d_query_vk_poll,
1883 .query_issue = wined3d_query_timestamp_vk_issue,
1884 .query_destroy = wined3d_query_vk_destroy,
1885};
1886
1888{
1891 .query_destroy = wined3d_query_vk_destroy,
1892};
1893
1895 void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
1896{
1897 struct wined3d_query_data_timestamp_disjoint *disjoint_data;
1898 const struct wined3d_query_ops *ops = &wined3d_query_vk_ops;
1899 struct wined3d_query_vk *query_vk;
1900 unsigned int data_size;
1901 void *data;
1902
1903 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1904 device, type, parent, parent_ops, query);
1905
1906 switch (type)
1907 {
1910 data_size = sizeof(BOOL);
1911 break;
1912
1914 data_size = sizeof(uint64_t);
1915 break;
1916
1919 {
1920 WARN("Timestamp queries not supported.\n");
1922 }
1924 data_size = sizeof(uint64_t);
1925 break;
1926
1929 {
1930 WARN("Timestamp queries not supported.\n");
1932 }
1934 data_size = sizeof(struct wined3d_query_data_timestamp_disjoint);
1935 break;
1936
1938 data_size = sizeof(struct wined3d_query_data_pipeline_statistics);
1939 break;
1940
1947 {
1948 WARN("Stream output queries not supported.\n");
1950 }
1951 data_size = sizeof(struct wined3d_query_data_so_statistics);
1952 break;
1953
1954 default:
1955 FIXME("Unhandled query type %#x.\n", type);
1957 }
1958
1959 if (!(query_vk = calloc(1, sizeof(*query_vk) + data_size)))
1960 return E_OUTOFMEMORY;
1961 data = query_vk + 1;
1962
1963 wined3d_query_init(&query_vk->q, device, type, data, data_size, ops, parent, parent_ops);
1964 query_vk->q.poll_in_cs = false;
1965
1966 switch (type)
1967 {
1970 break;
1971
1973 disjoint_data = data;
1974 disjoint_data->frequency = 1000000000 / wined3d_adapter_vk(device->adapter)->device_limits.timestampPeriod;
1975 disjoint_data->disjoint = FALSE;
1976 break;
1977
1978 default:
1979 break;
1980 }
1981
1982 TRACE("Created query %p.\n", query_vk);
1983 *query = &query_vk->q;
1984
1985 return WINED3D_OK;
1986}
1987
1989 void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
1990{
1991 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1992 device, type, parent, parent_ops, query);
1993
1994 return device->adapter->adapter_ops->adapter_create_query(device, type, parent, parent_ops, query);
1995}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
Definition: list.h:39
void wined3d_context_gl_free_fence(struct wined3d_fence *fence)
Definition: context_gl.c:966
void wined3d_context_gl_free_timestamp_query(struct wined3d_timestamp_query *query)
Definition: context_gl.c:1006
void wined3d_context_gl_free_pipeline_statistics_query(struct wined3d_pipeline_statistics_query *query)
Definition: context_gl.c:1084
void wined3d_context_gl_free_so_statistics_query(struct wined3d_so_statistics_query *query)
Definition: context_gl.c:1046
struct wined3d_context_gl * wined3d_context_gl_reacquire(struct wined3d_context_gl *context_gl)
Definition: context_gl.c:4378
void wined3d_context_gl_alloc_pipeline_statistics_query(struct wined3d_context_gl *context_gl, struct wined3d_pipeline_statistics_query *query)
Definition: context_gl.c:1065
void wined3d_context_gl_alloc_occlusion_query(struct wined3d_context_gl *context_gl, struct wined3d_occlusion_query *query)
Definition: context_gl.c:877
void wined3d_context_gl_alloc_so_statistics_query(struct wined3d_context_gl *context_gl, struct wined3d_so_statistics_query *query)
Definition: context_gl.c:1024
void wined3d_context_gl_free_occlusion_query(struct wined3d_occlusion_query *query)
Definition: context_gl.c:906
void wined3d_context_gl_alloc_fence(struct wined3d_context_gl *context_gl, struct wined3d_fence *fence)
Definition: context_gl.c:925
void wined3d_context_gl_alloc_timestamp_query(struct wined3d_context_gl *context_gl, struct wined3d_timestamp_query *query)
Definition: context_gl.c:985
void wined3d_context_vk_end_current_render_pass(struct wined3d_context_vk *context_vk)
Definition: context_vk.c:1564
VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk)
Definition: context_vk.c:1805
void wined3d_context_vk_destroy_vk_event(struct wined3d_context_vk *context_vk, VkEvent vk_event, uint64_t command_buffer_id)
Definition: context_vk.c:1067
bool wined3d_context_vk_allocate_query(struct wined3d_context_vk *context_vk, enum wined3d_query_type type, struct wined3d_query_pool_idx_vk *pool_idx)
Definition: context_vk.c:1623
void wined3d_cs_destroy_object(struct wined3d_cs *cs, void(*callback)(void *object), void *object)
Definition: cs.c:2299
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define free
Definition: debug_ros.c:5
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
void CDECL wined3d_device_context_issue_query(struct wined3d_device_context *context, struct wined3d_query *query, unsigned int flags)
Definition: device.c:4639
static void wined3d_so_statistics_query_ops_destroy(struct wined3d_query *query)
Definition: query.c:1208
static HRESULT wined3d_timestamp_disjoint_query_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
Definition: query.c:1168
static HRESULT wined3d_pipeline_query_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
Definition: query.c:1281
static const struct wined3d_query_ops wined3d_query_event_vk_ops
Definition: query.c:1835
static struct wined3d_so_statistics_query * wined3d_so_statistics_query_from_query(struct wined3d_query *query)
Definition: query.c:167
static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:604
static void wined3d_so_statistics_query_end(struct wined3d_so_statistics_query *query, struct wined3d_context_gl *context_gl)
Definition: query.c:793
static void wined3d_pipeline_query_ops_destroy(struct wined3d_query *query)
Definition: query.c:1266
void wined3d_query_vk_resume(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk)
Definition: query.c:1579
static void wined3d_query_vk_destroy(struct wined3d_query *query)
Definition: query.c:1739
static UINT64 get_query_result64(GLuint id, const struct wined3d_gl_info *gl_info)
Definition: query.c:119
static BOOL wined3d_query_timestamp_vk_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:1842
static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query, uint32_t flags)
Definition: query.c:507
static BOOL wined3d_event_query_ops_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:584
enum wined3d_query_type CDECL wined3d_query_get_type(const struct wined3d_query *query)
Definition: query.c:577
static void wined3d_timestamp_query_ops_destroy(struct wined3d_query *query)
Definition: query.c:1112
static const struct wined3d_query_ops wined3d_query_vk_ops
Definition: query.c:1757
HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, void *data, UINT data_size, uint32_t flags)
Definition: query.c:452
static BOOL wined3d_pipeline_query_ops_poll(struct wined3d_query *query, uint32_t flags)
Definition: query.c:887
static void wined3d_query_vk_begin(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer)
Definition: query.c:1542
static BOOL wined3d_so_statistics_query_ops_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:811
static BOOL wined3d_query_buffer_queue_result(struct wined3d_context_gl *context_gl, struct wined3d_query *query, GLuint id)
Definition: query.c:75
static BOOL wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:748
static const struct wined3d_query_ops wined3d_query_timestamp_disjoint_vk_ops
Definition: query.c:1887
void wined3d_fence_issue(struct wined3d_fence *fence, struct wined3d_device *device)
Definition: query.c:331
bool wined3d_query_pool_vk_init(struct wined3d_query_pool_vk *pool_vk, struct wined3d_context_vk *context_vk, enum wined3d_query_type type, struct list *free_pools)
Definition: query.c:1390
static BOOL wined3d_query_vk_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:1642
static void wined3d_query_vk_remove_pending_queries(struct wined3d_context_vk *context_vk, struct wined3d_query_vk *query_vk)
Definition: query.c:1631
static struct wined3d_event_query * wined3d_event_query_from_query(struct wined3d_query *query)
Definition: query.c:152
static HRESULT wined3d_timestamp_query_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
Definition: query.c:1128
void wined3d_query_vk_suspend(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk)
Definition: query.c:1587
HRESULT wined3d_query_gl_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
Definition: query.c:1309
static const struct wined3d_query_ops pipeline_query_ops
Definition: query.c:1274
static BOOL wined3d_query_vk_poll(struct wined3d_query *query, uint32_t flags)
Definition: query.c:1605
void wined3d_fence_destroy(struct wined3d_fence *fence)
Definition: query.c:373
HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:498
static struct wined3d_timestamp_query * wined3d_timestamp_query_from_query(struct wined3d_query *query)
Definition: query.c:162
void *CDECL wined3d_query_get_parent(const struct wined3d_query *query)
Definition: query.c:570
static BOOL wined3d_pipeline_query_ops_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:951
static const struct wined3d_query_ops timestamp_disjoint_query_ops
Definition: query.c:1161
void wined3d_query_pool_vk_cleanup(struct wined3d_query_pool_vk *pool_vk, struct wined3d_context_vk *context_vk)
Definition: query.c:1378
static void wined3d_occlusion_query_ops_destroy(struct wined3d_query *query)
Definition: query.c:1068
static BOOL wined3d_query_event_vk_poll(struct wined3d_query *query, uint32_t flags)
Definition: query.c:1764
void wined3d_query_pool_vk_mark_free(struct wined3d_context_vk *context_vk, struct wined3d_query_pool_vk *pool_vk, uint32_t start, uint32_t count)
Definition: query.c:1366
ULONG CDECL wined3d_query_incref(struct wined3d_query *query)
Definition: query.c:413
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)
Definition: query.c:1988
static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query, uint32_t flags)
Definition: query.c:677
static HRESULT wined3d_so_statistics_query_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
Definition: query.c:1224
static struct wined3d_pipeline_statistics_query * wined3d_pipeline_statistics_query_from_query(struct wined3d_query *query)
Definition: query.c:172
HRESULT wined3d_fence_create(struct wined3d_device *device, struct wined3d_fence **fence)
Definition: query.c:390
static void wined3d_query_destroy_object(void *object)
Definition: query.c:422
UINT CDECL wined3d_query_get_data_size(const struct wined3d_query *query)
Definition: query.c:491
enum wined3d_fence_result wined3d_fence_test(const struct wined3d_fence *fence, struct wined3d_device *device, uint32_t flags)
Definition: query.c:178
ULONG CDECL wined3d_query_decref(struct wined3d_query *query)
Definition: query.c:432
static void wined3d_query_create_buffer_object(struct wined3d_context_gl *context_gl, struct wined3d_query *query)
Definition: query.c:39
static void wined3d_query_vk_end(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer)
Definition: query.c:1561
static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *query, uint32_t flags)
Definition: query.c:741
static void wined3d_event_query_ops_destroy(struct wined3d_query *query)
Definition: query.c:1023
bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk, struct wined3d_device_vk *device_vk, const struct wined3d_query_pool_idx_vk *pool_idx)
Definition: query.c:1459
static BOOL wined3d_timestamp_query_ops_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:712
static const struct wined3d_query_ops wined3d_query_timestamp_vk_ops
Definition: query.c:1880
static void wined3d_timestamp_disjoint_query_ops_destroy(struct wined3d_query *query)
Definition: query.c:1156
static void wined3d_fence_free(struct wined3d_fence *fence)
Definition: query.c:367
static BOOL wined3d_so_statistics_query_ops_poll(struct wined3d_query *query, uint32_t flags)
Definition: query.c:755
bool wined3d_query_pool_vk_allocate_query(struct wined3d_query_pool_vk *pool_vk, size_t *idx)
Definition: query.c:1357
static const struct wined3d_query_ops occlusion_query_ops
Definition: query.c:1077
enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence, struct wined3d_device *device)
Definition: query.c:256
void wined3d_query_gl_destroy_buffer_object(struct wined3d_context_gl *context_gl, struct wined3d_query *query)
Definition: query.c:56
static BOOL wined3d_query_event_vk_issue(struct wined3d_query *query, uint32_t flags)
Definition: query.c:1778
static BOOL wined3d_event_query_ops_poll(struct wined3d_query *query, uint32_t flags)
Definition: query.c:539
HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
Definition: query.c:1894
static struct wined3d_occlusion_query * wined3d_occlusion_query_from_query(struct wined3d_query *query)
Definition: query.c:157
static void wined3d_query_pool_vk_mark_complete(struct wined3d_query_pool_vk *pool_vk, size_t idx, struct wined3d_context_vk *context_vk)
Definition: query.c:1346
static void wined3d_pipeline_statistics_query_end(struct wined3d_pipeline_statistics_query *query, struct wined3d_context_gl *context_gl)
Definition: query.c:932
static BOOL wined3d_query_buffer_is_valid(struct wined3d_query *query)
Definition: query.c:34
static HRESULT wined3d_event_query_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
Definition: query.c:1038
static HRESULT wined3d_fence_init(struct wined3d_fence *fence, const struct wined3d_gl_info *gl_info)
Definition: query.c:379
static const struct wined3d_query_ops event_query_ops
Definition: query.c:1031
static void wined3d_query_buffer_invalidate(struct wined3d_query *query)
Definition: query.c:27
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_parent_ops *parent_ops)
Definition: query.c:135
static const struct wined3d_query_ops so_statistics_query_ops
Definition: query.c:1217
static const struct wined3d_query_ops timestamp_query_ops
Definition: query.c:1121
static HRESULT wined3d_occlusion_query_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
Definition: query.c:1084
unsigned int idx
Definition: utils.c:40
const char * wined3d_debug_vkresult(VkResult vr)
Definition: utils.c:5463
BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
Definition: utils.c:6740
static WCHAR available[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2402
#define CDECL
Definition: compat.h:29
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
return ret
Definition: mutex.c:147
r parent
Definition: btrfs.c:3010
switch(r->id)
Definition: btrfs.c:3046
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
unsigned int GLenum
Definition: gl.h:150
unsigned int GLuint
Definition: gl.h:159
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define GL_MAP_READ_BIT
Definition: glext.h:1793
uint64_t GLuint64
Definition: glext.h:5568
#define GL_TIMESTAMP
Definition: glext.h:2037
#define GL_QUERY_RESULT
Definition: glext.h:334
#define GL_PRIMITIVES_GENERATED
Definition: glext.h:550
#define GL_ALREADY_SIGNALED
Definition: glext.h:1926
GLbitfield flags
Definition: glext.h:7161
struct __GLsync * GLsync
Definition: glext.h:5569
#define GL_MAP_WRITE_BIT
Definition: glext.h:1794
#define GL_QUERY_RESULT_AVAILABLE
Definition: glext.h:335
GLuint64EXT * result
Definition: glext.h:11304
#define GL_SAMPLES_PASSED
Definition: glext.h:356
#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
Definition: glext.h:551
#define GL_GEOMETRY_SHADER_INVOCATIONS
Definition: glext.h:2051
#define GL_CONDITION_SATISFIED
Definition: glext.h:1928
#define GL_TIMEOUT_EXPIRED
Definition: glext.h:1927
#define GL_WAIT_FAILED
Definition: glext.h:1929
#define GL_SYNC_FLUSH_COMMANDS_BIT
Definition: glext.h:1930
#define GL_SYNC_GPU_COMMANDS_COMPLETE
Definition: glext.h:1923
#define GL_ALL_COMPLETED_NV
Definition: glext.h:3621
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT
Definition: sysinfo.c:13
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define min(a, b)
Definition: monoChain.cc:55
#define uint64_t
Definition: nsiface.idl:62
#define BOOL
Definition: nt_native.h:43
#define calloc
Definition: rosglue.h:14
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
const void * pNext
Definition: vulkan.h:8621
VkStructureType sType
Definition: vulkan.h:8620
VkEventCreateFlags flags
Definition: vulkan.h:8622
VkQueryPipelineStatisticFlags pipelineStatistics
Definition: vulkan.h:13483
VkQueryPoolCreateFlags flags
Definition: vulkan.h:13480
const void * pNext
Definition: vulkan.h:13479
VkStructureType sType
Definition: vulkan.h:13478
VkQueryType queryType
Definition: vulkan.h:13481
Definition: devices.h:37
struct wined3d_gl_info gl_info
Definition: wined3d_gl.h:800
struct wined3d_vk_info vk_info
Definition: wined3d_vk.h:728
VkPhysicalDeviceLimits device_limits
Definition: wined3d_vk.h:733
struct wined3d_context c
Definition: wined3d_gl.h:601
const struct wined3d_gl_info * gl_info
Definition: wined3d_gl.h:603
struct list active_queries
Definition: wined3d_vk.h:648
struct list completed_query_pools
Definition: wined3d_vk.h:649
struct wined3d_command_buffer_vk current_command_buffer
Definition: wined3d_vk.h:617
uint64_t completed_command_buffer_id
Definition: wined3d_vk.h:618
const struct wined3d_vk_info * vk_info
Definition: wined3d_vk.h:590
VkRenderPass vk_render_pass
Definition: wined3d_vk.h:634
struct list render_pass_queries
Definition: wined3d_vk.h:647
struct wined3d_context c
Definition: wined3d_vk.h:588
struct wined3d_device d
Definition: wined3d_vk.h:821
VkDevice vk_device
Definition: wined3d_vk.h:825
struct wined3d_vk_info vk_info
Definition: wined3d_vk.h:830
struct wined3d_context_vk context_vk
Definition: wined3d_vk.h:823
uint32_t timestamp_bits
Definition: wined3d_vk.h:828
struct wined3d_fence fence
Definition: wined3d_gl.h:476
union wined3d_gl_fence_object object
Definition: wined3d_gl.h:457
struct wined3d_context_gl * context_gl
Definition: wined3d_gl.h:458
BOOL supported[WINED3D_GL_EXT_COUNT]
Definition: wined3d_gl.h:347
struct wined3d_context_gl * context_gl
Definition: wined3d_gl.h:486
struct wined3d_query_data_pipeline_statistics statistics
Definition: wined3d_gl.h:549
union wined3d_gl_pipeline_statistics_query u
Definition: wined3d_gl.h:547
struct wined3d_context_gl * context_gl
Definition: wined3d_gl.h:548
struct wined3d_query_pool_vk * pool_vk
Definition: wined3d_vk.h:385
uint32_t allocated[WINED3D_BITMAP_SIZE(WINED3D_QUERY_POOL_SIZE)]
Definition: wined3d_vk.h:371
struct list * free_list
Definition: wined3d_vk.h:367
uint32_t completed[WINED3D_BITMAP_SIZE(WINED3D_QUERY_POOL_SIZE)]
Definition: wined3d_vk.h:372
struct list completed_entry
Definition: wined3d_vk.h:365
VkQueryPool vk_query_pool
Definition: wined3d_vk.h:368
struct wined3d_query_pool_idx_vk * pending
Definition: wined3d_vk.h:404
struct wined3d_query_pool_idx_vk pool_idx
Definition: wined3d_vk.h:398
uint64_t command_buffer_id
Definition: wined3d_vk.h:400
struct list entry
Definition: wined3d_vk.h:397
SIZE_T pending_count
Definition: wined3d_vk.h:403
struct wined3d_query q
Definition: wined3d_vk.h:395
VkEvent vk_event
Definition: wined3d_vk.h:402
SIZE_T pending_size
Definition: wined3d_vk.h:403
uint32_t control_flags
Definition: wined3d_vk.h:401
const struct wined3d_parent_ops * parent_ops
struct wined3d_query_data_so_statistics statistics
Definition: wined3d_gl.h:519
struct wined3d_context_gl * context_gl
Definition: wined3d_gl.h:517
union wined3d_gl_so_statistics_query u
Definition: wined3d_gl.h:516
struct wined3d_context_gl * context_gl
Definition: wined3d_gl.h:497
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
struct wined3d_gl_pipeline_statistics_query::@344 query
struct wined3d_gl_so_statistics_query::@343 query
@ VK_QUERY_CONTROL_PRECISE_BIT
Definition: vulkan.h:4459
void VKAPI_CALL vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query)
VkResult VKAPI_CALL vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool)
void VKAPI_CALL vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags)
VkResult VKAPI_CALL vkGetEventStatus(VkDevice device, VkEvent event)
@ VK_QUERY_TYPE_PIPELINE_STATISTICS
Definition: vulkan.h:4510
@ VK_QUERY_TYPE_OCCLUSION
Definition: vulkan.h:4509
@ VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT
Definition: vulkan.h:4513
@ VK_QUERY_TYPE_TIMESTAMP
Definition: vulkan.h:4511
VkResult VKAPI_CALL vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void *pData, VkDeviceSize stride, VkQueryResultFlags flags)
VkResult VKAPI_CALL vkCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkEvent *pEvent)
void VKAPI_CALL vkDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator)
void VKAPI_CALL vkCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index)
VkResult VKAPI_CALL vkResetEvent(VkDevice device, VkEvent event)
@ VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT
Definition: vulkan.h:4466
@ VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT
Definition: vulkan.h:4468
@ VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT
Definition: vulkan.h:4465
@ VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT
Definition: vulkan.h:4474
@ VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT
Definition: vulkan.h:4472
@ VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT
Definition: vulkan.h:4467
@ VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT
Definition: vulkan.h:4469
@ VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT
Definition: vulkan.h:4470
@ VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT
Definition: vulkan.h:4473
@ VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT
Definition: vulkan.h:4471
@ VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT
Definition: vulkan.h:4475
VkResult
Definition: vulkan.h:4639
@ VK_SUCCESS
Definition: vulkan.h:4672
@ VK_EVENT_SET
Definition: vulkan.h:4675
@ VK_EVENT_RESET
Definition: vulkan.h:4676
@ VK_NOT_READY
Definition: vulkan.h:4673
void VKAPI_CALL vkCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index)
void VKAPI_CALL vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask)
#define VK_NULL_HANDLE
Definition: vulkan.h:861
void VKAPI_CALL vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)
@ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
Definition: vulkan.h:4288
@ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
Definition: vulkan.h:4285
@ VK_QUERY_RESULT_64_BIT
Definition: vulkan.h:4490
void VKAPI_CALL vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator)
@ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO
Definition: vulkan.h:4975
@ VK_STRUCTURE_TYPE_EVENT_CREATE_INFO
Definition: vulkan.h:4974
#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB
Definition: wgl.h:4181
#define GL_PRIMITIVES_SUBMITTED_ARB
Definition: wgl.h:3231
#define GL_MAP_COHERENT_BIT
Definition: wgl.h:2142
#define GL_MAP_PERSISTENT_BIT
Definition: wgl.h:2147
#define GL_CLIPPING_INPUT_PRIMITIVES_ARB
Definition: wgl.h:402
#define GL_VERTEX_SHADER_INVOCATIONS_ARB
Definition: wgl.h:4942
#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB
Definition: wgl.h:404
#define GL_COMPUTE_SHADER_INVOCATIONS_ARB
Definition: wgl.h:694
#define GL_VERTICES_SUBMITTED_ARB
Definition: wgl.h:4968
#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB
Definition: wgl.h:1570
#define GL_TESS_CONTROL_SHADER_PATCHES_ARB
Definition: wgl.h:4172
#define GL_QUERY_BUFFER
Definition: wgl.h:3358
#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB
Definition: wgl.h:1457
#define WINED3DISSUE_BEGIN
Definition: wined3d.h:781
#define WINED3D_OK
Definition: wined3d.h:33
#define WINED3DGETDATA_FLUSH
Definition: wined3d.h:783
#define WINED3DERR_NOTAVAILABLE
Definition: wined3d.h:42
wined3d_query_type
Definition: wined3d.h:725
@ WINED3D_QUERY_TYPE_TIMESTAMP_FREQ
Definition: wined3d.h:733
@ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2
Definition: wined3d.h:746
@ WINED3D_QUERY_TYPE_SO_STATISTICS
Definition: wined3d.h:742
@ WINED3D_QUERY_TYPE_PIPELINE_STATISTICS
Definition: wined3d.h:741
@ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0
Definition: wined3d.h:744
@ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1
Definition: wined3d.h:745
@ WINED3D_QUERY_TYPE_TIMESTAMP
Definition: wined3d.h:731
@ WINED3D_QUERY_TYPE_EVENT
Definition: wined3d.h:729
@ WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT
Definition: wined3d.h:732
@ WINED3D_QUERY_TYPE_OCCLUSION
Definition: wined3d.h:730
@ WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3
Definition: wined3d.h:747
#define WINED3DISSUE_END
Definition: wined3d.h:782
#define WINED3DERR_INVALIDCALL
Definition: wined3d.h:44
@ ARB_PIPELINE_STATISTICS_QUERY
Definition: wined3d_gl.h:98
@ WINED3D_GL_PRIMITIVE_QUERY
Definition: wined3d_gl.h:234
@ APPLE_FENCE
Definition: wined3d_gl.h:46
@ ARB_BUFFER_STORAGE
Definition: wined3d_gl.h:55
@ ARB_SYNC
Definition: wined3d_gl.h:122
@ NV_FENCE
Definition: wined3d_gl.h:205
@ ARB_TRANSFORM_FEEDBACK3
Definition: wined3d_gl.h:150
@ ARB_OCCLUSION_QUERY
Definition: wined3d_gl.h:97
@ ARB_QUERY_BUFFER_OBJECT
Definition: wined3d_gl.h:104
@ ARB_TIMER_QUERY
Definition: wined3d_gl.h:148
#define GL_EXTCALL(f)
Definition: wined3d_gl.h:360
static bool wined3d_fence_supported(const struct wined3d_gl_info *gl_info)
Definition: wined3d_gl.h:394
wined3d_fence_result
Definition: wined3d_gl.h:446
@ WINED3D_FENCE_WRONG_THREAD
Definition: wined3d_gl.h:450
@ WINED3D_FENCE_OK
Definition: wined3d_gl.h:447
@ WINED3D_FENCE_WAITING
Definition: wined3d_gl.h:448
@ WINED3D_FENCE_ERROR
Definition: wined3d_gl.h:451
@ WINED3D_FENCE_NOT_STARTED
Definition: wined3d_gl.h:449
#define checkGLcall(A)
Definition: wined3d_gl.h:402
void WINAPI wined3d_mutex_unlock(void)
Definition: wined3d_main.c:544
void WINAPI wined3d_mutex_lock(void)
Definition: wined3d_main.c:539
static BOOL wined3d_bitmap_clear(uint32_t *map, unsigned int idx)
static unsigned int wined3d_bitmap_ffz(const uint32_t *bitmap, unsigned int bit_count, unsigned int start)
#define WINED3D_QUERY_POOL_SIZE
static void context_release(struct wined3d_context *context)
static BOOL wined3d_bitmap_set(uint32_t *map, unsigned int idx)
@ QUERY_BUILDING
@ QUERY_CREATED
static struct wined3d_context * context_acquire(struct wined3d_device *device, struct wined3d_texture *texture, unsigned int sub_resource_idx)
#define WINED3D_QUERY_VK_FLAG_RENDER_PASS
Definition: wined3d_vk.h:391
static void wined3d_context_vk_reference_query(const struct wined3d_context_vk *context_vk, struct wined3d_query_vk *query_vk)
Definition: wined3d_vk.h:1118
#define WINED3D_QUERY_VK_FLAG_ACTIVE
Definition: wined3d_vk.h:389
#define VK_CALL(f)
Definition: wined3d_vk.h:272
@ WINED3D_VK_EXT_TRANSFORM_FEEDBACK
Definition: wined3d_vk.h:245
#define WINED3D_QUERY_VK_FLAG_STARTED
Definition: wined3d_vk.h:390
#define S_FALSE
Definition: winerror.h:3451
#define poll
Definition: wintirpc.h:59