Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / mesa / src / gallium / drivers / nvfx / nvfx_query.c
blob3cd6bf1e477d6870a96afecdf5ed90779549322f
1 #include "pipe/p_context.h"
3 #include "nvfx_context.h"
5 struct nvfx_query {
6 struct list_head list;
7 struct nouveau_resource *object;
8 unsigned type;
9 boolean ready;
10 uint64_t result;
13 static INLINE struct nvfx_query *
14 nvfx_query(struct pipe_query *pipe)
16 return (struct nvfx_query *)pipe;
19 static struct pipe_query *
20 nvfx_query_create(struct pipe_context *pipe, unsigned query_type)
22 struct nvfx_query *q;
24 q = CALLOC(1, sizeof(struct nvfx_query));
25 q->type = query_type;
27 assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
29 return (struct pipe_query *)q;
32 static void
33 nvfx_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
35 struct nvfx_query *q = nvfx_query(pq);
37 if (q->object)
39 nouveau_resource_free(&q->object);
40 LIST_DEL(&q->list);
42 FREE(q);
45 static void
46 nvfx_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
48 struct nvfx_context *nvfx = nvfx_context(pipe);
49 struct nvfx_query *q = nvfx_query(pq);
50 struct nvfx_screen *screen = nvfx->screen;
51 struct nouveau_channel *chan = screen->base.channel;
52 struct nouveau_grobj *eng3d = screen->eng3d;
53 uint64_t tmp;
55 assert(!nvfx->query);
57 /* Happens when end_query() is called, then another begin_query()
58 * without querying the result in-between. For now we'll wait for
59 * the existing query to notify completion, but it could be better.
61 if (q->object)
62 pipe->get_query_result(pipe, pq, 1, &tmp);
64 while (nouveau_resource_alloc(nvfx->screen->query_heap, 1, NULL, &q->object))
66 struct nvfx_query* oldestq;
67 assert(!LIST_IS_EMPTY(&nvfx->screen->query_list));
68 oldestq = LIST_ENTRY(struct nvfx_query, nvfx->screen->query_list.next, list);
69 pipe->get_query_result(pipe, (struct pipe_query*)oldestq, 1, &tmp);
72 LIST_ADDTAIL(&q->list, &nvfx->screen->query_list);
74 nouveau_notifier_reset(nvfx->screen->query, q->object->start);
76 BEGIN_RING(chan, eng3d, NV30_3D_QUERY_RESET, 1);
77 OUT_RING(chan, 1);
78 BEGIN_RING(chan, eng3d, NV30_3D_QUERY_ENABLE, 1);
79 OUT_RING(chan, 1);
81 q->ready = FALSE;
83 nvfx->query = pq;
86 static void
87 nvfx_query_end(struct pipe_context *pipe, struct pipe_query *pq)
89 struct nvfx_context *nvfx = nvfx_context(pipe);
90 struct nouveau_channel *chan = nvfx->screen->base.channel;
91 struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
92 struct nvfx_query *q = nvfx_query(pq);
94 assert(nvfx->query == pq);
96 BEGIN_RING(chan, eng3d, NV30_3D_QUERY_GET, 1);
97 OUT_RING (chan, (0x01 << NV30_3D_QUERY_GET_UNK24__SHIFT) |
98 ((q->object->start * 32) << NV30_3D_QUERY_GET_OFFSET__SHIFT));
99 BEGIN_RING(chan, eng3d, NV30_3D_QUERY_ENABLE, 1);
100 OUT_RING(chan, 0);
101 FIRE_RING(chan);
103 nvfx->query = 0;
106 static boolean
107 nvfx_query_result(struct pipe_context *pipe, struct pipe_query *pq,
108 boolean wait, void *vresult)
110 uint64_t *result = (uint64_t *)vresult;
111 struct nvfx_context *nvfx = nvfx_context(pipe);
112 struct nvfx_query *q = nvfx_query(pq);
114 if (!q->ready) {
115 unsigned status;
117 status = nouveau_notifier_status(nvfx->screen->query,
118 q->object->start);
119 if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
120 if (wait == FALSE)
121 return FALSE;
123 nouveau_notifier_wait_status(nvfx->screen->query,
124 q->object->start,
125 NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
128 q->result = nouveau_notifier_return_val(nvfx->screen->query,
129 q->object->start);
130 q->ready = TRUE;
131 nouveau_resource_free(&q->object);
132 LIST_DEL(&q->list);
135 *result = q->result;
136 return TRUE;
139 void
140 nvfx_init_query_functions(struct nvfx_context *nvfx)
142 nvfx->pipe.create_query = nvfx_query_create;
143 nvfx->pipe.destroy_query = nvfx_query_destroy;
144 nvfx->pipe.begin_query = nvfx_query_begin;
145 nvfx->pipe.end_query = nvfx_query_end;
146 nvfx->pipe.get_query_result = nvfx_query_result;