1 #include "pipe/p_context.h"
3 #include "nv40_context.h"
6 struct nouveau_resource
*object
;
12 static INLINE
struct nv40_query
*
13 nv40_query(struct pipe_query
*pipe
)
15 return (struct nv40_query
*)pipe
;
18 static struct pipe_query
*
19 nv40_query_create(struct pipe_context
*pipe
, unsigned query_type
)
23 q
= CALLOC(1, sizeof(struct nv40_query
));
26 return (struct pipe_query
*)q
;
30 nv40_query_destroy(struct pipe_context
*pipe
, struct pipe_query
*pq
)
32 struct nv40_context
*nv40
= nv40_context(pipe
);
33 struct nv40_query
*q
= nv40_query(pq
);
36 nv40
->nvws
->res_free(&q
->object
);
41 nv40_query_begin(struct pipe_context
*pipe
, struct pipe_query
*pq
)
43 struct nv40_context
*nv40
= nv40_context(pipe
);
44 struct nv40_query
*q
= nv40_query(pq
);
46 assert(q
->type
== PIPE_QUERY_OCCLUSION_COUNTER
);
48 /* Happens when end_query() is called, then another begin_query()
49 * without querying the result in-between. For now we'll wait for
50 * the existing query to notify completion, but it could be better.
54 pipe
->get_query_result(pipe
, pq
, 1, &tmp
);
57 if (nv40
->nvws
->res_alloc(nv40
->screen
->query_heap
, 1, NULL
, &q
->object
))
59 nv40
->nvws
->notifier_reset(nv40
->screen
->query
, q
->object
->start
);
61 BEGIN_RING(curie
, NV40TCL_QUERY_RESET
, 1);
63 BEGIN_RING(curie
, NV40TCL_QUERY_UNK17CC
, 1);
70 nv40_query_end(struct pipe_context
*pipe
, struct pipe_query
*pq
)
72 struct nv40_context
*nv40
= nv40_context(pipe
);
73 struct nv40_query
*q
= nv40_query(pq
);
75 BEGIN_RING(curie
, NV40TCL_QUERY_GET
, 1);
76 OUT_RING ((0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT
) |
77 ((q
->object
->start
* 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT
));
82 nv40_query_result(struct pipe_context
*pipe
, struct pipe_query
*pq
,
83 boolean wait
, uint64
*result
)
85 struct nv40_context
*nv40
= nv40_context(pipe
);
86 struct nv40_query
*q
= nv40_query(pq
);
87 struct nouveau_winsys
*nvws
= nv40
->nvws
;
89 assert(q
->object
&& q
->type
== PIPE_QUERY_OCCLUSION_COUNTER
);
94 status
= nvws
->notifier_status(nv40
->screen
->query
,
96 if (status
!= NV_NOTIFY_STATE_STATUS_COMPLETED
) {
99 nvws
->notifier_wait(nv40
->screen
->query
, q
->object
->start
,
100 NV_NOTIFY_STATE_STATUS_COMPLETED
,
104 q
->result
= nvws
->notifier_retval(nv40
->screen
->query
,
107 nvws
->res_free(&q
->object
);
115 nv40_init_query_functions(struct nv40_context
*nv40
)
117 nv40
->pipe
.create_query
= nv40_query_create
;
118 nv40
->pipe
.destroy_query
= nv40_query_destroy
;
119 nv40
->pipe
.begin_query
= nv40_query_begin
;
120 nv40
->pipe
.end_query
= nv40_query_end
;
121 nv40
->pipe
.get_query_result
= nv40_query_result
;