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 pipe_buffer
*buffer
;
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 pipe_winsys
*ws
= pipe
->winsys
;
45 struct nv50_query
*q
= CALLOC_STRUCT(nv50_query
);
47 assert (q
->type
== PIPE_QUERY_OCCLUSION_COUNTER
);
50 q
->buffer
= ws
->buffer_create(ws
, 256, 0, 16);
56 return (struct pipe_query
*)q
;
60 nv50_query_destroy(struct pipe_context
*pipe
, struct pipe_query
*pq
)
62 struct nv50_query
*q
= nv50_query(pq
);
65 pipe_buffer_reference(pipe
->screen
, &q
->buffer
, NULL
);
71 nv50_query_begin(struct pipe_context
*pipe
, struct pipe_query
*pq
)
73 struct nv50_context
*nv50
= nv50_context(pipe
);
74 struct nouveau_channel
*chan
= nv50
->screen
->nvws
->channel
;
75 struct nouveau_grobj
*tesla
= nv50
->screen
->tesla
;
76 struct nv50_query
*q
= nv50_query(pq
);
78 BEGIN_RING(chan
, tesla
, 0x1530, 1);
80 BEGIN_RING(chan
, tesla
, 0x1514, 1);
87 nv50_query_end(struct pipe_context
*pipe
, struct pipe_query
*pq
)
89 struct nv50_context
*nv50
= nv50_context(pipe
);
90 struct nouveau_channel
*chan
= nv50
->screen
->nvws
->channel
;
91 struct nouveau_grobj
*tesla
= nv50
->screen
->tesla
;
92 struct nv50_query
*q
= nv50_query(pq
);
95 BEGIN_RING(chan
, tesla
, 0x1b00, 4);
96 OUT_RELOCh(chan
, q
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
97 OUT_RELOCl(chan
, q
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
98 OUT_RING (chan
, 0x00000000);
99 OUT_RING (chan
, 0x0100f002);
104 nv50_query_result(struct pipe_context
*pipe
, struct pipe_query
*pq
,
105 boolean wait
, uint64_t *result
)
107 struct pipe_winsys
*ws
= pipe
->winsys
;
108 struct nv50_query
*q
= nv50_query(pq
);
110 /*XXX: Want to be able to return FALSE here instead of blocking
111 * until the result is available..
115 uint32_t *map
= ws
->buffer_map(ws
, q
->buffer
,
116 PIPE_BUFFER_USAGE_CPU_READ
);
119 ws
->buffer_unmap(ws
, q
->buffer
);
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
;