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