1 #include "pipe/p_context.h"
3 #include "nvfx_context.h"
7 struct nouveau_resource *object;
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)
24 q = CALLOC(1, sizeof(struct nvfx_query));
27 assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
29 return (struct pipe_query *)q;
33 nvfx_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
35 struct nvfx_query *q = nvfx_query(pq);
39 nouveau_resource_free(&q->object);
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;
55 /* Happens when end_query() is called, then another begin_query()
56 * without querying the result in-between. For now we'll wait for
57 * the existing query to notify completion, but it could be better.
60 pipe->get_query_result(pipe, pq, 1, &tmp);
62 while (nouveau_resource_alloc(nvfx->screen->query_heap, 1, NULL, &q->object))
64 struct nvfx_query* oldestq;
65 assert(!LIST_IS_EMPTY(&nvfx->screen->query_list));
66 oldestq = LIST_ENTRY(struct nvfx_query, nvfx->screen->query_list.next, list);
67 pipe->get_query_result(pipe, (struct pipe_query*)oldestq, 1, &tmp);
70 LIST_ADDTAIL(&q->list, &nvfx->screen->query_list);
72 nouveau_notifier_reset(nvfx->screen->query, q->object->start);
74 BEGIN_RING(chan, eng3d, NV34TCL_QUERY_RESET, 1);
76 BEGIN_RING(chan, eng3d, NV34TCL_QUERY_UNK17CC, 1);
83 nvfx_query_end(struct pipe_context *pipe, struct pipe_query *pq)
85 struct nvfx_context *nvfx = nvfx_context(pipe);
86 struct nvfx_screen *screen = nvfx->screen;
87 struct nouveau_channel *chan = screen->base.channel;
88 struct nouveau_grobj *eng3d = screen->eng3d;
89 struct nvfx_query *q = nvfx_query(pq);
91 BEGIN_RING(chan, eng3d, NV34TCL_QUERY_GET, 1);
92 OUT_RING (chan, (0x01 << NV34TCL_QUERY_GET_UNK24_SHIFT) |
93 ((q->object->start * 32) << NV34TCL_QUERY_GET_OFFSET_SHIFT));
98 nvfx_query_result(struct pipe_context *pipe, struct pipe_query *pq,
99 boolean wait, void *vresult)
101 uint64_t *result = (uint64_t *)vresult;
102 struct nvfx_context *nvfx = nvfx_context(pipe);
103 struct nvfx_query *q = nvfx_query(pq);
108 status = nouveau_notifier_status(nvfx->screen->query,
110 if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
114 nouveau_notifier_wait_status(nvfx->screen->query,
116 NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
119 q->result = nouveau_notifier_return_val(nvfx->screen->query,
122 nouveau_resource_free(&q->object);
131 nvfx_init_query_functions(struct nvfx_context *nvfx)
133 nvfx->pipe.create_query = nvfx_query_create;
134 nvfx->pipe.destroy_query = nvfx_query_destroy;
135 nvfx->pipe.begin_query = nvfx_query_begin;
136 nvfx->pipe.end_query = nvfx_query_end;
137 nvfx->pipe.get_query_result = nvfx_query_result;