1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2007 VMware, Inc.
4848b8605Smrg * Copyright 2010 VMware, Inc.
5848b8605Smrg * All Rights Reserved.
6848b8605Smrg *
7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
8848b8605Smrg * copy of this software and associated documentation files (the
9848b8605Smrg * "Software"), to deal in the Software without restriction, including
10848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
11848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
12848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
13848b8605Smrg * the following conditions:
14848b8605Smrg *
15848b8605Smrg * The above copyright notice and this permission notice (including the
16848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
17848b8605Smrg * of the Software.
18848b8605Smrg *
19848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22848b8605Smrg * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
23848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26848b8605Smrg *
27848b8605Smrg **************************************************************************/
28848b8605Smrg
29848b8605Smrg/* Authors:
30848b8605Smrg *    Keith Whitwell, Qicheng Christopher Li, Brian Paul
31848b8605Smrg */
32848b8605Smrg
33848b8605Smrg#include "draw/draw_context.h"
34848b8605Smrg#include "pipe/p_defines.h"
35848b8605Smrg#include "util/u_memory.h"
36b8e80941Smrg#include "util/os_time.h"
37848b8605Smrg#include "lp_context.h"
38848b8605Smrg#include "lp_flush.h"
39848b8605Smrg#include "lp_fence.h"
40848b8605Smrg#include "lp_query.h"
41848b8605Smrg#include "lp_screen.h"
42848b8605Smrg#include "lp_state.h"
43848b8605Smrg#include "lp_rast.h"
44848b8605Smrg
45848b8605Smrg
46848b8605Smrgstatic struct llvmpipe_query *llvmpipe_query( struct pipe_query *p )
47848b8605Smrg{
48848b8605Smrg   return (struct llvmpipe_query *)p;
49848b8605Smrg}
50848b8605Smrg
51848b8605Smrgstatic struct pipe_query *
52848b8605Smrgllvmpipe_create_query(struct pipe_context *pipe,
53848b8605Smrg                      unsigned type,
54848b8605Smrg                      unsigned index)
55848b8605Smrg{
56848b8605Smrg   struct llvmpipe_query *pq;
57848b8605Smrg
58848b8605Smrg   assert(type < PIPE_QUERY_TYPES);
59848b8605Smrg
60848b8605Smrg   pq = CALLOC_STRUCT( llvmpipe_query );
61848b8605Smrg
62848b8605Smrg   if (pq) {
63848b8605Smrg      pq->type = type;
64848b8605Smrg   }
65848b8605Smrg
66848b8605Smrg   return (struct pipe_query *) pq;
67848b8605Smrg}
68848b8605Smrg
69848b8605Smrg
70848b8605Smrgstatic void
71848b8605Smrgllvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
72848b8605Smrg{
73848b8605Smrg   struct llvmpipe_query *pq = llvmpipe_query(q);
74848b8605Smrg
75848b8605Smrg   /* Ideally we would refcount queries & not get destroyed until the
76848b8605Smrg    * last scene had finished with us.
77848b8605Smrg    */
78848b8605Smrg   if (pq->fence) {
79848b8605Smrg      if (!lp_fence_issued(pq->fence))
80848b8605Smrg         llvmpipe_flush(pipe, NULL, __FUNCTION__);
81848b8605Smrg
82848b8605Smrg      if (!lp_fence_signalled(pq->fence))
83848b8605Smrg         lp_fence_wait(pq->fence);
84848b8605Smrg
85848b8605Smrg      lp_fence_reference(&pq->fence, NULL);
86848b8605Smrg   }
87848b8605Smrg
88848b8605Smrg   FREE(pq);
89848b8605Smrg}
90848b8605Smrg
91848b8605Smrg
92848b8605Smrgstatic boolean
93848b8605Smrgllvmpipe_get_query_result(struct pipe_context *pipe,
94848b8605Smrg                          struct pipe_query *q,
95848b8605Smrg                          boolean wait,
96848b8605Smrg                          union pipe_query_result *vresult)
97848b8605Smrg{
98848b8605Smrg   struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
99848b8605Smrg   unsigned num_threads = MAX2(1, screen->num_threads);
100848b8605Smrg   struct llvmpipe_query *pq = llvmpipe_query(q);
101848b8605Smrg   uint64_t *result = (uint64_t *)vresult;
102848b8605Smrg   int i;
103848b8605Smrg
104848b8605Smrg   if (pq->fence) {
105848b8605Smrg      /* only have a fence if there was a scene */
106848b8605Smrg      if (!lp_fence_signalled(pq->fence)) {
107848b8605Smrg         if (!lp_fence_issued(pq->fence))
108848b8605Smrg            llvmpipe_flush(pipe, NULL, __FUNCTION__);
109848b8605Smrg
110848b8605Smrg         if (!wait)
111848b8605Smrg            return FALSE;
112848b8605Smrg
113848b8605Smrg         lp_fence_wait(pq->fence);
114848b8605Smrg      }
115848b8605Smrg   }
116848b8605Smrg
117848b8605Smrg   /* Sum the results from each of the threads:
118848b8605Smrg    */
119848b8605Smrg   *result = 0;
120848b8605Smrg
121848b8605Smrg   switch (pq->type) {
122848b8605Smrg   case PIPE_QUERY_OCCLUSION_COUNTER:
123848b8605Smrg      for (i = 0; i < num_threads; i++) {
124848b8605Smrg         *result += pq->end[i];
125848b8605Smrg      }
126848b8605Smrg      break;
127848b8605Smrg   case PIPE_QUERY_OCCLUSION_PREDICATE:
128b8e80941Smrg   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
129848b8605Smrg      for (i = 0; i < num_threads; i++) {
130848b8605Smrg         /* safer (still not guaranteed) when there's an overflow */
131848b8605Smrg         vresult->b = vresult->b || pq->end[i];
132848b8605Smrg      }
133848b8605Smrg      break;
134848b8605Smrg   case PIPE_QUERY_TIMESTAMP:
135848b8605Smrg      for (i = 0; i < num_threads; i++) {
136848b8605Smrg         if (pq->end[i] > *result) {
137848b8605Smrg            *result = pq->end[i];
138848b8605Smrg         }
139848b8605Smrg      }
140848b8605Smrg      break;
141848b8605Smrg   case PIPE_QUERY_TIMESTAMP_DISJOINT: {
142848b8605Smrg      struct pipe_query_data_timestamp_disjoint *td =
143848b8605Smrg         (struct pipe_query_data_timestamp_disjoint *)vresult;
144848b8605Smrg      /* os_get_time_nano return nanoseconds */
145848b8605Smrg      td->frequency = UINT64_C(1000000000);
146848b8605Smrg      td->disjoint = FALSE;
147848b8605Smrg   }
148848b8605Smrg      break;
149848b8605Smrg   case PIPE_QUERY_GPU_FINISHED:
150848b8605Smrg      vresult->b = TRUE;
151848b8605Smrg      break;
152848b8605Smrg   case PIPE_QUERY_PRIMITIVES_GENERATED:
153848b8605Smrg      *result = pq->num_primitives_generated;
154848b8605Smrg      break;
155848b8605Smrg   case PIPE_QUERY_PRIMITIVES_EMITTED:
156848b8605Smrg      *result = pq->num_primitives_written;
157848b8605Smrg      break;
158848b8605Smrg   case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
159b8e80941Smrg   case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE:
160848b8605Smrg      vresult->b = pq->num_primitives_generated > pq->num_primitives_written;
161848b8605Smrg      break;
162848b8605Smrg   case PIPE_QUERY_SO_STATISTICS: {
163848b8605Smrg      struct pipe_query_data_so_statistics *stats =
164848b8605Smrg         (struct pipe_query_data_so_statistics *)vresult;
165848b8605Smrg      stats->num_primitives_written = pq->num_primitives_written;
166848b8605Smrg      stats->primitives_storage_needed = pq->num_primitives_generated;
167848b8605Smrg   }
168848b8605Smrg      break;
169848b8605Smrg   case PIPE_QUERY_PIPELINE_STATISTICS: {
170848b8605Smrg      struct pipe_query_data_pipeline_statistics *stats =
171848b8605Smrg         (struct pipe_query_data_pipeline_statistics *)vresult;
172848b8605Smrg      /* only ps_invocations come from binned query */
173848b8605Smrg      for (i = 0; i < num_threads; i++) {
174848b8605Smrg         pq->stats.ps_invocations += pq->end[i];
175848b8605Smrg      }
176848b8605Smrg      pq->stats.ps_invocations *= LP_RASTER_BLOCK_SIZE * LP_RASTER_BLOCK_SIZE;
177848b8605Smrg      *stats = pq->stats;
178848b8605Smrg   }
179848b8605Smrg      break;
180848b8605Smrg   default:
181848b8605Smrg      assert(0);
182848b8605Smrg      break;
183848b8605Smrg   }
184848b8605Smrg
185848b8605Smrg   return TRUE;
186848b8605Smrg}
187848b8605Smrg
188848b8605Smrg
189b8e80941Smrgstatic boolean
190848b8605Smrgllvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
191848b8605Smrg{
192848b8605Smrg   struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
193848b8605Smrg   struct llvmpipe_query *pq = llvmpipe_query(q);
194848b8605Smrg
195848b8605Smrg   /* Check if the query is already in the scene.  If so, we need to
196848b8605Smrg    * flush the scene now.  Real apps shouldn't re-use a query in a
197848b8605Smrg    * frame of rendering.
198848b8605Smrg    */
199848b8605Smrg   if (pq->fence && !lp_fence_issued(pq->fence)) {
200848b8605Smrg      llvmpipe_finish(pipe, __FUNCTION__);
201848b8605Smrg   }
202848b8605Smrg
203848b8605Smrg
204848b8605Smrg   memset(pq->start, 0, sizeof(pq->start));
205848b8605Smrg   memset(pq->end, 0, sizeof(pq->end));
206848b8605Smrg   lp_setup_begin_query(llvmpipe->setup, pq);
207848b8605Smrg
208848b8605Smrg   switch (pq->type) {
209848b8605Smrg   case PIPE_QUERY_PRIMITIVES_EMITTED:
210848b8605Smrg      pq->num_primitives_written = llvmpipe->so_stats.num_primitives_written;
211848b8605Smrg      break;
212848b8605Smrg   case PIPE_QUERY_PRIMITIVES_GENERATED:
213848b8605Smrg      pq->num_primitives_generated = llvmpipe->so_stats.primitives_storage_needed;
214848b8605Smrg      break;
215848b8605Smrg   case PIPE_QUERY_SO_STATISTICS:
216848b8605Smrg      pq->num_primitives_written = llvmpipe->so_stats.num_primitives_written;
217848b8605Smrg      pq->num_primitives_generated = llvmpipe->so_stats.primitives_storage_needed;
218848b8605Smrg      break;
219848b8605Smrg   case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
220b8e80941Smrg   case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE:
221848b8605Smrg      pq->num_primitives_written = llvmpipe->so_stats.num_primitives_written;
222848b8605Smrg      pq->num_primitives_generated = llvmpipe->so_stats.primitives_storage_needed;
223848b8605Smrg      break;
224848b8605Smrg   case PIPE_QUERY_PIPELINE_STATISTICS:
225848b8605Smrg      /* reset our cache */
226848b8605Smrg      if (llvmpipe->active_statistics_queries == 0) {
227848b8605Smrg         memset(&llvmpipe->pipeline_statistics, 0,
228848b8605Smrg                sizeof(llvmpipe->pipeline_statistics));
229848b8605Smrg      }
230848b8605Smrg      memcpy(&pq->stats, &llvmpipe->pipeline_statistics, sizeof(pq->stats));
231848b8605Smrg      llvmpipe->active_statistics_queries++;
232848b8605Smrg      break;
233848b8605Smrg   case PIPE_QUERY_OCCLUSION_COUNTER:
234848b8605Smrg   case PIPE_QUERY_OCCLUSION_PREDICATE:
235b8e80941Smrg   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
236848b8605Smrg      llvmpipe->active_occlusion_queries++;
237848b8605Smrg      llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
238848b8605Smrg      break;
239848b8605Smrg   default:
240848b8605Smrg      break;
241848b8605Smrg   }
242b8e80941Smrg   return true;
243848b8605Smrg}
244848b8605Smrg
245848b8605Smrg
246b8e80941Smrgstatic bool
247848b8605Smrgllvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
248848b8605Smrg{
249848b8605Smrg   struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
250848b8605Smrg   struct llvmpipe_query *pq = llvmpipe_query(q);
251848b8605Smrg
252848b8605Smrg   lp_setup_end_query(llvmpipe->setup, pq);
253848b8605Smrg
254848b8605Smrg   switch (pq->type) {
255848b8605Smrg
256848b8605Smrg   case PIPE_QUERY_PRIMITIVES_EMITTED:
257848b8605Smrg      pq->num_primitives_written =
258848b8605Smrg         llvmpipe->so_stats.num_primitives_written - pq->num_primitives_written;
259848b8605Smrg      break;
260848b8605Smrg   case PIPE_QUERY_PRIMITIVES_GENERATED:
261848b8605Smrg      pq->num_primitives_generated =
262848b8605Smrg         llvmpipe->so_stats.primitives_storage_needed - pq->num_primitives_generated;
263848b8605Smrg      break;
264848b8605Smrg   case PIPE_QUERY_SO_STATISTICS:
265848b8605Smrg      pq->num_primitives_written =
266848b8605Smrg         llvmpipe->so_stats.num_primitives_written - pq->num_primitives_written;
267848b8605Smrg      pq->num_primitives_generated =
268848b8605Smrg         llvmpipe->so_stats.primitives_storage_needed - pq->num_primitives_generated;
269848b8605Smrg      break;
270848b8605Smrg   case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
271b8e80941Smrg   case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE:
272848b8605Smrg      pq->num_primitives_written =
273848b8605Smrg         llvmpipe->so_stats.num_primitives_written - pq->num_primitives_written;
274848b8605Smrg      pq->num_primitives_generated =
275848b8605Smrg         llvmpipe->so_stats.primitives_storage_needed - pq->num_primitives_generated;
276848b8605Smrg      break;
277848b8605Smrg   case PIPE_QUERY_PIPELINE_STATISTICS:
278848b8605Smrg      pq->stats.ia_vertices =
279848b8605Smrg         llvmpipe->pipeline_statistics.ia_vertices - pq->stats.ia_vertices;
280848b8605Smrg      pq->stats.ia_primitives =
281848b8605Smrg         llvmpipe->pipeline_statistics.ia_primitives - pq->stats.ia_primitives;
282848b8605Smrg      pq->stats.vs_invocations =
283848b8605Smrg         llvmpipe->pipeline_statistics.vs_invocations - pq->stats.vs_invocations;
284848b8605Smrg      pq->stats.gs_invocations =
285848b8605Smrg         llvmpipe->pipeline_statistics.gs_invocations - pq->stats.gs_invocations;
286848b8605Smrg      pq->stats.gs_primitives =
287848b8605Smrg         llvmpipe->pipeline_statistics.gs_primitives - pq->stats.gs_primitives;
288848b8605Smrg      pq->stats.c_invocations =
289848b8605Smrg         llvmpipe->pipeline_statistics.c_invocations - pq->stats.c_invocations;
290848b8605Smrg      pq->stats.c_primitives =
291848b8605Smrg         llvmpipe->pipeline_statistics.c_primitives - pq->stats.c_primitives;
292848b8605Smrg      pq->stats.ps_invocations =
293848b8605Smrg         llvmpipe->pipeline_statistics.ps_invocations - pq->stats.ps_invocations;
294848b8605Smrg
295848b8605Smrg      llvmpipe->active_statistics_queries--;
296848b8605Smrg      break;
297848b8605Smrg   case PIPE_QUERY_OCCLUSION_COUNTER:
298848b8605Smrg   case PIPE_QUERY_OCCLUSION_PREDICATE:
299b8e80941Smrg   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
300848b8605Smrg      assert(llvmpipe->active_occlusion_queries);
301848b8605Smrg      llvmpipe->active_occlusion_queries--;
302848b8605Smrg      llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
303848b8605Smrg      break;
304848b8605Smrg   default:
305848b8605Smrg      break;
306848b8605Smrg   }
307b8e80941Smrg
308b8e80941Smrg   return true;
309848b8605Smrg}
310848b8605Smrg
311848b8605Smrgboolean
312848b8605Smrgllvmpipe_check_render_cond(struct llvmpipe_context *lp)
313848b8605Smrg{
314848b8605Smrg   struct pipe_context *pipe = &lp->pipe;
315848b8605Smrg   boolean b, wait;
316848b8605Smrg   uint64_t result;
317848b8605Smrg
318848b8605Smrg   if (!lp->render_cond_query)
319848b8605Smrg      return TRUE; /* no query predicate, draw normally */
320848b8605Smrg
321848b8605Smrg   wait = (lp->render_cond_mode == PIPE_RENDER_COND_WAIT ||
322848b8605Smrg           lp->render_cond_mode == PIPE_RENDER_COND_BY_REGION_WAIT);
323848b8605Smrg
324848b8605Smrg   b = pipe->get_query_result(pipe, lp->render_cond_query, wait, (void*)&result);
325848b8605Smrg   if (b)
326b8e80941Smrg      return ((!result) == lp->render_cond_cond);
327848b8605Smrg   else
328848b8605Smrg      return TRUE;
329848b8605Smrg}
330848b8605Smrg
331b8e80941Smrgstatic void
332b8e80941Smrgllvmpipe_set_active_query_state(struct pipe_context *pipe, boolean enable)
333b8e80941Smrg{
334b8e80941Smrg}
335b8e80941Smrg
336848b8605Smrgvoid llvmpipe_init_query_funcs(struct llvmpipe_context *llvmpipe )
337848b8605Smrg{
338848b8605Smrg   llvmpipe->pipe.create_query = llvmpipe_create_query;
339848b8605Smrg   llvmpipe->pipe.destroy_query = llvmpipe_destroy_query;
340848b8605Smrg   llvmpipe->pipe.begin_query = llvmpipe_begin_query;
341848b8605Smrg   llvmpipe->pipe.end_query = llvmpipe_end_query;
342848b8605Smrg   llvmpipe->pipe.get_query_result = llvmpipe_get_query_result;
343b8e80941Smrg   llvmpipe->pipe.set_active_query_state = llvmpipe_set_active_query_state;
344848b8605Smrg}
345848b8605Smrg
346848b8605Smrg
347