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;
56
/* Happens when end_query() is called, then another begin_query()
57
* without querying the result in-between. For now we'll wait for
58
* the existing query to notify completion, but it could be better.
61
pipe->get_query_result(pipe, pq, 1, &tmp);
63
while (nouveau_resource_alloc(nvfx->screen->query_heap, 1, NULL, &q->object))
65
struct nvfx_query* oldestq;
66
assert(!LIST_IS_EMPTY(&nvfx->screen->query_list));
67
oldestq = LIST_ENTRY(struct nvfx_query, nvfx->screen->query_list.next, list);
68
pipe->get_query_result(pipe, (struct pipe_query*)oldestq, 1, &tmp);
71
LIST_ADDTAIL(&q->list, &nvfx->screen->query_list);
73
nouveau_notifier_reset(nvfx->screen->query, q->object->start);
76
OUT_RING(chan, RING_3D(NV30_3D_QUERY_RESET, 1));
78
OUT_RING(chan, RING_3D(NV30_3D_QUERY_ENABLE, 1));
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 nvfx_query *q = nvfx_query(pq);
93
assert(nvfx->query == pq);
96
OUT_RING(chan, RING_3D(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
OUT_RING(chan, RING_3D(NV30_3D_QUERY_ENABLE, 1));
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);
117
status = nouveau_notifier_status(nvfx->screen->query,
119
if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
123
nouveau_notifier_wait_status(nvfx->screen->query,
125
NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
128
q->result = nouveau_notifier_return_val(nvfx->screen->query,
131
nouveau_resource_free(&q->object);
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;