1 #include "pipe/p_context.h"
3 #include "nv30_context.h"
6 struct nouveau_resource
*object
;
12 static INLINE
struct nv30_query
*
13 nv30_query(struct pipe_query
*pipe
)
15 return (struct nv30_query
*)pipe
;
18 static struct pipe_query
*
19 nv30_query_create(struct pipe_context
*pipe
, unsigned query_type
)
23 q
= CALLOC(1, sizeof(struct nv30_query
));
26 return (struct pipe_query
*)q
;
30 nv30_query_destroy(struct pipe_context
*pipe
, struct pipe_query
*pq
)
32 struct nv30_query
*q
= nv30_query(pq
);
35 nouveau_resource_free(&q
->object
);
40 nv30_query_begin(struct pipe_context
*pipe
, struct pipe_query
*pq
)
42 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
43 struct nv30_query
*q
= nv30_query(pq
);
44 struct nvfx_screen
*screen
= nvfx
->screen
;
45 struct nouveau_channel
*chan
= screen
->base
.channel
;
46 struct nouveau_grobj
*eng3d
= screen
->eng3d
;
48 assert(q
->type
== PIPE_QUERY_OCCLUSION_COUNTER
);
50 /* Happens when end_query() is called, then another begin_query()
51 * without querying the result in-between. For now we'll wait for
52 * the existing query to notify completion, but it could be better.
56 pipe
->get_query_result(pipe
, pq
, 1, &tmp
);
59 if (nouveau_resource_alloc(nvfx
->screen
->query_heap
, 1, NULL
, &q
->object
))
61 nouveau_notifier_reset(nvfx
->screen
->query
, q
->object
->start
);
63 BEGIN_RING(chan
, eng3d
, NV34TCL_QUERY_RESET
, 1);
65 BEGIN_RING(chan
, eng3d
, NV34TCL_QUERY_UNK17CC
, 1);
72 nv30_query_end(struct pipe_context
*pipe
, struct pipe_query
*pq
)
74 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
75 struct nvfx_screen
*screen
= nvfx
->screen
;
76 struct nouveau_channel
*chan
= screen
->base
.channel
;
77 struct nouveau_grobj
*eng3d
= screen
->eng3d
;
78 struct nv30_query
*q
= nv30_query(pq
);
80 BEGIN_RING(chan
, eng3d
, NV34TCL_QUERY_GET
, 1);
81 OUT_RING (chan
, (0x01 << NV34TCL_QUERY_GET_UNK24_SHIFT
) |
82 ((q
->object
->start
* 32) << NV34TCL_QUERY_GET_OFFSET_SHIFT
));
87 nv30_query_result(struct pipe_context
*pipe
, struct pipe_query
*pq
,
88 boolean wait
, uint64_t *result
)
90 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
91 struct nv30_query
*q
= nv30_query(pq
);
93 assert(q
->object
&& q
->type
== PIPE_QUERY_OCCLUSION_COUNTER
);
98 status
= nouveau_notifier_status(nvfx
->screen
->query
,
100 if (status
!= NV_NOTIFY_STATE_STATUS_COMPLETED
) {
104 nouveau_notifier_wait_status(nvfx
->screen
->query
,
106 NV_NOTIFY_STATE_STATUS_COMPLETED
, 0);
109 q
->result
= nouveau_notifier_return_val(nvfx
->screen
->query
,
112 nouveau_resource_free(&q
->object
);
120 nv30_init_query_functions(struct nvfx_context
*nvfx
)
122 nvfx
->pipe
.create_query
= nv30_query_create
;
123 nvfx
->pipe
.destroy_query
= nv30_query_destroy
;
124 nvfx
->pipe
.begin_query
= nv30_query_begin
;
125 nvfx
->pipe
.end_query
= nv30_query_end
;
126 nvfx
->pipe
.get_query_result
= nv30_query_result
;