2 * Copyright 2008 Ben Skeggs
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #include "pipe/p_context.h"
24 #include "util/u_inlines.h"
26 #include "nv50_context.h"
29 struct nouveau_bo
*bo
;
35 static INLINE
struct nv50_query
*
36 nv50_query(struct pipe_query
*pipe
)
38 return (struct nv50_query
*)pipe
;
41 static struct pipe_query
*
42 nv50_query_create(struct pipe_context
*pipe
, unsigned type
)
44 struct nouveau_device
*dev
= nouveau_screen(pipe
->screen
)->device
;
45 struct nv50_query
*q
= CALLOC_STRUCT(nv50_query
);
48 assert (q
->type
== PIPE_QUERY_OCCLUSION_COUNTER
);
51 ret
= nouveau_bo_new(dev
, NOUVEAU_BO_GART
| NOUVEAU_BO_MAP
, 256,
58 return (struct pipe_query
*)q
;
62 nv50_query_destroy(struct pipe_context
*pipe
, struct pipe_query
*pq
)
64 struct nv50_query
*q
= nv50_query(pq
);
67 nouveau_bo_ref(NULL
, &q
->bo
);
73 nv50_query_begin(struct pipe_context
*pipe
, struct pipe_query
*pq
)
75 struct nv50_context
*nv50
= nv50_context(pipe
);
76 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
77 struct nouveau_grobj
*tesla
= nv50
->screen
->tesla
;
78 struct nv50_query
*q
= nv50_query(pq
);
80 BEGIN_RING(chan
, tesla
, NV50TCL_SAMPLECNT_RESET
, 1);
82 BEGIN_RING(chan
, tesla
, NV50TCL_SAMPLECNT_ENABLE
, 1);
89 nv50_query_end(struct pipe_context
*pipe
, struct pipe_query
*pq
)
91 struct nv50_context
*nv50
= nv50_context(pipe
);
92 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
93 struct nouveau_grobj
*tesla
= nv50
->screen
->tesla
;
94 struct nv50_query
*q
= nv50_query(pq
);
96 MARK_RING (chan
, 5, 2); /* flush on lack of space or relocs */
97 BEGIN_RING(chan
, tesla
, NV50TCL_QUERY_ADDRESS_HIGH
, 4);
98 OUT_RELOCh(chan
, q
->bo
, 0, NOUVEAU_BO_GART
| NOUVEAU_BO_WR
);
99 OUT_RELOCl(chan
, q
->bo
, 0, NOUVEAU_BO_GART
| NOUVEAU_BO_WR
);
100 OUT_RING (chan
, 0x00000000);
101 OUT_RING (chan
, 0x0100f002);
103 BEGIN_RING(chan
, tesla
, NV50TCL_SAMPLECNT_ENABLE
, 1);
108 nv50_query_result(struct pipe_context
*pipe
, struct pipe_query
*pq
,
109 boolean wait
, uint64_t *result
)
111 struct nv50_query
*q
= nv50_query(pq
);
115 ret
= nouveau_bo_map(q
->bo
, NOUVEAU_BO_RD
|
116 (wait
? 0 : NOUVEAU_BO_NOWAIT
));
119 q
->result
= ((uint32_t *)q
->bo
->map
)[1];
121 nouveau_bo_unmap(q
->bo
);
129 nv50_render_condition(struct pipe_context
*pipe
,
130 struct pipe_query
*pq
, uint mode
)
132 struct nv50_context
*nv50
= nv50_context(pipe
);
133 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
134 struct nouveau_grobj
*tesla
= nv50
->screen
->tesla
;
135 struct nv50_query
*q
;
138 BEGIN_RING(chan
, tesla
, NV50TCL_COND_MODE
, 1);
139 OUT_RING (chan
, NV50TCL_COND_MODE_ALWAYS
);
144 if (mode
== PIPE_RENDER_COND_WAIT
||
145 mode
== PIPE_RENDER_COND_BY_REGION_WAIT
) {
146 /* XXX: big fence, FIFO semaphore might be better */
147 BEGIN_RING(chan
, tesla
, 0x0110, 1);
151 BEGIN_RING(chan
, tesla
, NV50TCL_COND_ADDRESS_HIGH
, 3);
152 OUT_RELOCh(chan
, q
->bo
, 0, NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
153 OUT_RELOCl(chan
, q
->bo
, 0, NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
154 OUT_RING (chan
, NV50TCL_COND_MODE_RES
);
158 nv50_init_query_functions(struct nv50_context
*nv50
)
160 nv50
->pipe
.create_query
= nv50_query_create
;
161 nv50
->pipe
.destroy_query
= nv50_query_destroy
;
162 nv50
->pipe
.begin_query
= nv50_query_begin
;
163 nv50
->pipe
.end_query
= nv50_query_end
;
164 nv50
->pipe
.get_query_result
= nv50_query_result
;
165 nv50
->pipe
.render_condition
= nv50_render_condition
;