nouveau: add nv30.
[mesa.git] / src / mesa / pipe / nv30 / nv30_query.c
1 #include "pipe/p_context.h"
2
3 #include "nv30_context.h"
4
5 struct nv30_query {
6 struct nouveau_resource *object;
7 unsigned type;
8 boolean ready;
9 uint64_t result;
10 };
11
12 static inline struct nv30_query *
13 nv30_query(struct pipe_query *pipe)
14 {
15 return (struct nv30_query *)pipe;
16 }
17
18 static struct pipe_query *
19 nv30_query_create(struct pipe_context *pipe, unsigned query_type)
20 {
21 struct nv30_query *q;
22
23 q = calloc(1, sizeof(struct nv30_query));
24 q->type = query_type;
25
26 return (struct pipe_query *)q;
27 }
28
29 static void
30 nv30_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
31 {
32 struct nv30_context *nv30 = nv30_context(pipe);
33 struct nv30_query *q = nv30_query(pq);
34
35 if (q->object)
36 nv30->nvws->res_free(&q->object);
37 free(q);
38 }
39
40 static void
41 nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
42 {
43 struct nv30_context *nv30 = nv30_context(pipe);
44 struct nv30_query *q = nv30_query(pq);
45
46 assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
47
48 if (nv30->nvws->res_alloc(nv30->query_heap, 1, NULL, &q->object))
49 assert(0);
50 nv30->nvws->notifier_reset(nv30->query, q->object->start);
51
52 BEGIN_RING(rankine, NV34TCL_QUERY_RESET, 1);
53 OUT_RING (1);
54 BEGIN_RING(rankine, NV34TCL_QUERY_UNK17CC, 1);
55 OUT_RING (1);
56
57 q->ready = FALSE;
58 }
59
60 static void
61 nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq)
62 {
63 struct nv30_context *nv30 = nv30_context(pipe);
64 struct nv30_query *q = nv30_query(pq);
65
66 BEGIN_RING(rankine, NV34TCL_QUERY_GET, 1);
67 OUT_RING ((0x01 << NV34TCL_QUERY_GET_UNK24_SHIFT) |
68 ((q->object->start * 32) << NV34TCL_QUERY_GET_OFFSET_SHIFT));
69 FIRE_RING();
70 }
71
72 static boolean
73 nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq,
74 boolean wait, uint64 *result)
75 {
76 struct nv30_context *nv30 = nv30_context(pipe);
77 struct nv30_query *q = nv30_query(pq);
78 struct nouveau_winsys *nvws = nv30->nvws;
79
80 assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER);
81
82 if (!q->ready) {
83 unsigned status;
84
85 status = nvws->notifier_status(nv30->query, q->object->start);
86 if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
87 if (wait == FALSE)
88 return FALSE;
89 nvws->notifier_wait(nv30->query, q->object->start,
90 NV_NOTIFY_STATE_STATUS_COMPLETED,
91 0);
92 }
93
94 q->result = nvws->notifier_retval(nv30->query,
95 q->object->start);
96 q->ready = TRUE;
97 nvws->res_free(&q->object);
98 }
99
100 *result = q->result;
101 return TRUE;
102 }
103
104 void
105 nv30_init_query_functions(struct nv30_context *nv30)
106 {
107 nv30->pipe.create_query = nv30_query_create;
108 nv30->pipe.destroy_query = nv30_query_destroy;
109 nv30->pipe.begin_query = nv30_query_begin;
110 nv30->pipe.end_query = nv30_query_end;
111 nv30->pipe.get_query_result = nv30_query_result;
112 }