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 "pipe/p_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_VRAM
| 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
, 0x1530, 1);
82 BEGIN_RING(chan
, tesla
, 0x1514, 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
);
97 BEGIN_RING(chan
, tesla
, NV50TCL_QUERY_ADDRESS_HIGH
, 4);
98 OUT_RELOCh(chan
, q
->bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
99 OUT_RELOCl(chan
, q
->bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
100 OUT_RING (chan
, 0x00000000);
101 OUT_RING (chan
, 0x0100f002);
106 nv50_query_result(struct pipe_context
*pipe
, struct pipe_query
*pq
,
107 boolean wait
, uint64_t *result
)
109 struct nv50_query
*q
= nv50_query(pq
);
113 ret
= nouveau_bo_map(q
->bo
, NOUVEAU_BO_RD
|
114 wait
? 0 : NOUVEAU_BO_NOWAIT
);
117 q
->result
= ((uint32_t *)q
->bo
->map
)[1];
119 nouveau_bo_unmap(q
->bo
);
127 nv50_init_query_functions(struct nv50_context
*nv50
)
129 nv50
->pipe
.create_query
= nv50_query_create
;
130 nv50
->pipe
.destroy_query
= nv50_query_destroy
;
131 nv50
->pipe
.begin_query
= nv50_query_begin
;
132 nv50
->pipe
.end_query
= nv50_query_end
;
133 nv50
->pipe
.get_query_result
= nv50_query_result
;