bcd6fe0cf4980d6bfefdf1d981cdea0c560c4275
[mesa.git] / src / mesa / pipe / nv40 / nv40_query.c
1 #include "pipe/p_context.h"
2
3 #include "nv40_context.h"
4 #include "nv40_dma.h"
5
6 static uint
7 nv40_query_object_find(struct nv40_context *nv40, struct pipe_query_object *q)
8 {
9 int id;
10
11 for (id = 0; id < nv40->num_query_objects; id++) {
12 if (nv40->query_objects[id] == q)
13 return id;
14 }
15
16 return -1;
17 }
18
19 static void
20 nv40_query_begin(struct pipe_context *pipe, struct pipe_query_object *q)
21 {
22 struct nv40_context *nv40 = (struct nv40_context *)pipe;
23 int id;
24
25 assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
26
27 id = nv40_query_object_find(nv40, NULL);
28 assert(id >= 0);
29 nv40->query_objects[id] = q;
30
31 nv40->nvws->notifier_reset(nv40->query, id);
32 q->ready = 0;
33
34 BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1);
35 OUT_RING (1);
36 BEGIN_RING(curie, NV40TCL_QUERY_UNK17CC, 1);
37 OUT_RING (1);
38 }
39
40 static void
41 nv40_query_update(struct pipe_context *pipe, struct pipe_query_object *q)
42 {
43 struct nv40_context *nv40 = (struct nv40_context *)pipe;
44 int id;
45
46 id = nv40_query_object_find(nv40, q);
47 assert(id >= 0);
48
49 if (nv40->nvws->notifier_status(nv40->query, id) == 0) {
50 q->ready = 1;
51 q->count = nv40->nvws->notifier_retval(nv40->query, id);
52 nv40->query_objects[id] = NULL;
53 }
54 }
55
56 static void
57 nv40_query_wait(struct pipe_context *pipe, struct pipe_query_object *q)
58 {
59 nv40_query_update(pipe, q);
60 if (!q->ready) {
61 struct nv40_context *nv40 = (struct nv40_context *)pipe;
62 int id;
63
64 id = nv40_query_object_find(nv40, q);
65 assert(id >= 0);
66
67 nv40->nvws->notifier_wait(nv40->query, id, 0, 0);
68 nv40_query_update(pipe, q);
69 assert(q->ready);
70 }
71 }
72
73 static void
74 nv40_query_end(struct pipe_context *pipe, struct pipe_query_object *q)
75 {
76 struct nv40_context *nv40 = (struct nv40_context *)pipe;
77 int id;
78
79 id = nv40_query_object_find(nv40, q);
80 assert(id >= 0);
81
82 BEGIN_RING(curie, NV40TCL_QUERY_GET, 1);
83 OUT_RING ((0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT) |
84 ((id * 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT));
85 FIRE_RING ();
86
87 /*XXX: Some apps spin waiting for GL_QUERY_RESULT_AVAILABLE_ARB.
88 * Core mesa won't ask the driver to update the query object's
89 * status in this case, so the app waits forever.. fix this some
90 * day.
91 */
92 #if 0
93 nv40_query_update(pipe, q);
94 #else
95 nv40_query_wait(pipe, q);
96 #endif
97 }
98
99 void
100 nv40_init_query_functions(struct nv40_context *nv40)
101 {
102 nv40->pipe.begin_query = nv40_query_begin;
103 nv40->pipe.end_query = nv40_query_end;
104 nv40->pipe.wait_query = nv40_query_wait;
105 }