1/**********************************************************
2 * Copyright 2008-2015 VMware, Inc.  All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 **********************************************************/
25
26#include "pipe/p_state.h"
27#include "pipe/p_context.h"
28
29#include "util/u_bitmask.h"
30#include "util/u_memory.h"
31
32#include "svga_cmd.h"
33#include "svga_context.h"
34#include "svga_screen.h"
35#include "svga_resource_buffer.h"
36#include "svga_winsys.h"
37#include "svga_debug.h"
38
39
40/* Fixme: want a public base class for all pipe structs, even if there
41 * isn't much in them.
42 */
43struct pipe_query {
44   int dummy;
45};
46
47struct svga_query {
48   struct pipe_query base;
49   unsigned type;                  /**< PIPE_QUERY_x or SVGA_QUERY_x */
50   SVGA3dQueryType svga_type;      /**< SVGA3D_QUERYTYPE_x or unused */
51
52   unsigned id;                    /** Per-context query identifier */
53
54   struct pipe_fence_handle *fence;
55
56   /** For PIPE_QUERY_OCCLUSION_COUNTER / SVGA3D_QUERYTYPE_OCCLUSION */
57
58   /* For VGPU9 */
59   struct svga_winsys_buffer *hwbuf;
60   volatile SVGA3dQueryResult *queryResult;
61
62   /** For VGPU10 */
63   struct svga_winsys_gb_query *gb_query;
64   SVGA3dDXQueryFlags flags;
65   unsigned offset;                /**< offset to the gb_query memory */
66   struct pipe_query *predicate;   /** The associated query that can be used for predicate */
67
68   /** For non-GPU SVGA_QUERY_x queries */
69   uint64_t begin_count, end_count;
70};
71
72
73/** cast wrapper */
74static inline struct svga_query *
75svga_query(struct pipe_query *q)
76{
77   return (struct svga_query *)q;
78}
79
80/**
81 * VGPU9
82 */
83
84static boolean
85svga_get_query_result(struct pipe_context *pipe,
86                      struct pipe_query *q,
87                      boolean wait,
88                      union pipe_query_result *result);
89
90static enum pipe_error
91define_query_vgpu9(struct svga_context *svga,
92                   struct svga_query *sq)
93{
94   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
95
96   sq->hwbuf = svga_winsys_buffer_create(svga, 1,
97                                         SVGA_BUFFER_USAGE_PINNED,
98                                         sizeof *sq->queryResult);
99   if (!sq->hwbuf)
100      return PIPE_ERROR_OUT_OF_MEMORY;
101
102   sq->queryResult = (SVGA3dQueryResult *)
103                     sws->buffer_map(sws, sq->hwbuf, PIPE_TRANSFER_WRITE);
104   if (!sq->queryResult) {
105      sws->buffer_destroy(sws, sq->hwbuf);
106      return PIPE_ERROR_OUT_OF_MEMORY;
107   }
108
109   sq->queryResult->totalSize = sizeof *sq->queryResult;
110   sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
111
112   /* We request the buffer to be pinned and assume it is always mapped.
113    * The reason is that we don't want to wait for fences when checking the
114    * query status.
115    */
116   sws->buffer_unmap(sws, sq->hwbuf);
117
118   return PIPE_OK;
119}
120
121static enum pipe_error
122begin_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
123{
124   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
125   enum pipe_error ret = PIPE_OK;
126
127   if (sq->queryResult->state == SVGA3D_QUERYSTATE_PENDING) {
128      /* The application doesn't care for the pending query result.
129       * We cannot let go of the existing buffer and just get a new one
130       * because its storage may be reused for other purposes and clobbered
131       * by the host when it determines the query result.  So the only
132       * option here is to wait for the existing query's result -- not a
133       * big deal, given that no sane application would do this.
134       */
135       uint64_t result;
136       svga_get_query_result(&svga->pipe, &sq->base, TRUE, (void*)&result);
137       assert(sq->queryResult->state != SVGA3D_QUERYSTATE_PENDING);
138   }
139
140   sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
141   sws->fence_reference(sws, &sq->fence, NULL);
142
143   ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type);
144   if (ret != PIPE_OK) {
145      svga_context_flush(svga, NULL);
146      ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type);
147   }
148   return ret;
149}
150
151static enum pipe_error
152end_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
153{
154   enum pipe_error ret = PIPE_OK;
155
156   /* Set to PENDING before sending EndQuery. */
157   sq->queryResult->state = SVGA3D_QUERYSTATE_PENDING;
158
159   ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf);
160   if (ret != PIPE_OK) {
161      svga_context_flush(svga, NULL);
162      ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf);
163   }
164   return ret;
165}
166
167static boolean
168get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
169                       boolean wait, uint64_t *result)
170{
171   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
172   enum pipe_error ret;
173   SVGA3dQueryState state;
174
175   if (!sq->fence) {
176      /* The query status won't be updated by the host unless
177       * SVGA_3D_CMD_WAIT_FOR_QUERY is emitted. Unfortunately this will cause
178       * a synchronous wait on the host.
179       */
180      ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf);
181      if (ret != PIPE_OK) {
182         svga_context_flush(svga, NULL);
183         ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf);
184      }
185      assert (ret == PIPE_OK);
186      svga_context_flush(svga, &sq->fence);
187      assert(sq->fence);
188   }
189
190   state = sq->queryResult->state;
191   if (state == SVGA3D_QUERYSTATE_PENDING) {
192      if (!wait)
193         return FALSE;
194      sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
195      state = sq->queryResult->state;
196   }
197
198   assert(state == SVGA3D_QUERYSTATE_SUCCEEDED ||
199          state == SVGA3D_QUERYSTATE_FAILED);
200
201   *result = (uint64_t)sq->queryResult->result32;
202   return TRUE;
203}
204
205
206/**
207 * VGPU10
208 *
209 * There is one query mob allocated for each context to be shared by all
210 * query types. The mob is used to hold queries's state and result. Since
211 * each query result type is of different length, to ease the query allocation
212 * management, the mob is divided into memory blocks. Each memory block
213 * will hold queries of the same type. Multiple memory blocks can be allocated
214 * for a particular query type.
215 *
216 * Currently each memory block is of 184 bytes. We support up to 128
217 * memory blocks. The query memory size is arbitrary right now.
218 * Each occlusion query takes about 8 bytes. One memory block can accomodate
219 * 23 occlusion queries. 128 of those blocks can support up to 2944 occlusion
220 * queries. That seems reasonable for now. If we think this limit is
221 * not enough, we can increase the limit or try to grow the mob in runtime.
222 * Note, SVGA device does not impose one mob per context for queries,
223 * we could allocate multiple mobs for queries; however, wddm KMD does not
224 * currently support that.
225 *
226 * Also note that the GL guest driver does not issue any of the
227 * following commands: DXMoveQuery, DXBindAllQuery & DXReadbackAllQuery.
228 */
229#define SVGA_QUERY_MEM_BLOCK_SIZE    (sizeof(SVGADXQueryResultUnion) * 2)
230#define SVGA_QUERY_MEM_SIZE          (128 * SVGA_QUERY_MEM_BLOCK_SIZE)
231
232struct svga_qmem_alloc_entry
233{
234   unsigned start_offset;               /* start offset of the memory block */
235   unsigned block_index;                /* block index of the memory block */
236   unsigned query_size;                 /* query size in this memory block */
237   unsigned nquery;                     /* number of queries allocated */
238   struct util_bitmask *alloc_mask;     /* allocation mask */
239   struct svga_qmem_alloc_entry *next;  /* next memory block */
240};
241
242
243/**
244 * Allocate a memory block from the query object memory
245 * \return -1 if out of memory, else index of the query memory block
246 */
247static int
248allocate_query_block(struct svga_context *svga)
249{
250   int index;
251   unsigned offset;
252
253   /* Find the next available query block */
254   index = util_bitmask_add(svga->gb_query_alloc_mask);
255
256   if (index == UTIL_BITMASK_INVALID_INDEX)
257      return -1;
258
259   offset = index * SVGA_QUERY_MEM_BLOCK_SIZE;
260   if (offset >= svga->gb_query_len) {
261      unsigned i;
262
263      /**
264       * All the memory blocks are allocated, lets see if there is
265       * any empty memory block around that can be freed up.
266       */
267      index = -1;
268      for (i = 0; i < SVGA3D_QUERYTYPE_MAX && index == -1; i++) {
269         struct svga_qmem_alloc_entry *alloc_entry;
270         struct svga_qmem_alloc_entry *prev_alloc_entry = NULL;
271
272         alloc_entry = svga->gb_query_map[i];
273         while (alloc_entry && index == -1) {
274            if (alloc_entry->nquery == 0) {
275               /* This memory block is empty, it can be recycled. */
276               if (prev_alloc_entry) {
277                  prev_alloc_entry->next = alloc_entry->next;
278               } else {
279                  svga->gb_query_map[i] = alloc_entry->next;
280               }
281               index = alloc_entry->block_index;
282            } else {
283               prev_alloc_entry = alloc_entry;
284               alloc_entry = alloc_entry->next;
285            }
286         }
287      }
288   }
289
290   return index;
291}
292
293/**
294 * Allocate a slot in the specified memory block.
295 * All slots in this memory block are of the same size.
296 *
297 * \return -1 if out of memory, else index of the query slot
298 */
299static int
300allocate_query_slot(struct svga_context *svga,
301                    struct svga_qmem_alloc_entry *alloc)
302{
303   int index;
304   unsigned offset;
305
306   /* Find the next available slot */
307   index = util_bitmask_add(alloc->alloc_mask);
308
309   if (index == UTIL_BITMASK_INVALID_INDEX)
310      return -1;
311
312   offset = index * alloc->query_size;
313   if (offset >= SVGA_QUERY_MEM_BLOCK_SIZE)
314      return -1;
315
316   alloc->nquery++;
317
318   return index;
319}
320
321/**
322 * Deallocate the specified slot in the memory block.
323 * If all slots are freed up, then deallocate the memory block
324 * as well, so it can be allocated for other query type
325 */
326static void
327deallocate_query_slot(struct svga_context *svga,
328                      struct svga_qmem_alloc_entry *alloc,
329                      unsigned index)
330{
331   assert(index != UTIL_BITMASK_INVALID_INDEX);
332
333   util_bitmask_clear(alloc->alloc_mask, index);
334   alloc->nquery--;
335
336   /**
337    * Don't worry about deallocating the empty memory block here.
338    * The empty memory block will be recycled when no more memory block
339    * can be allocated.
340    */
341}
342
343static struct svga_qmem_alloc_entry *
344allocate_query_block_entry(struct svga_context *svga,
345                           unsigned len)
346{
347   struct svga_qmem_alloc_entry *alloc_entry;
348   int block_index = -1;
349
350   block_index = allocate_query_block(svga);
351   if (block_index == -1)
352      return NULL;
353   alloc_entry = CALLOC_STRUCT(svga_qmem_alloc_entry);
354   if (!alloc_entry)
355      return NULL;
356
357   alloc_entry->block_index = block_index;
358   alloc_entry->start_offset = block_index * SVGA_QUERY_MEM_BLOCK_SIZE;
359   alloc_entry->nquery = 0;
360   alloc_entry->alloc_mask = util_bitmask_create();
361   alloc_entry->next = NULL;
362   alloc_entry->query_size = len;
363
364   return alloc_entry;
365}
366
367/**
368 * Allocate a memory slot for a query of the specified type.
369 * It will first search through the memory blocks that are allocated
370 * for the query type. If no memory slot is available, it will try
371 * to allocate another memory block within the query object memory for
372 * this query type.
373 */
374static int
375allocate_query(struct svga_context *svga,
376               SVGA3dQueryType type,
377               unsigned len)
378{
379   struct svga_qmem_alloc_entry *alloc_entry;
380   int slot_index = -1;
381   unsigned offset;
382
383   assert(type < SVGA3D_QUERYTYPE_MAX);
384
385   alloc_entry = svga->gb_query_map[type];
386
387   if (!alloc_entry) {
388      /**
389       * No query memory block has been allocated for this query type,
390       * allocate one now
391       */
392      alloc_entry = allocate_query_block_entry(svga, len);
393      if (!alloc_entry)
394         return -1;
395      svga->gb_query_map[type] = alloc_entry;
396   }
397
398   /* Allocate a slot within the memory block allocated for this query type */
399   slot_index = allocate_query_slot(svga, alloc_entry);
400
401   if (slot_index == -1) {
402      /* This query memory block is full, allocate another one */
403      alloc_entry = allocate_query_block_entry(svga, len);
404      if (!alloc_entry)
405         return -1;
406      alloc_entry->next = svga->gb_query_map[type];
407      svga->gb_query_map[type] = alloc_entry;
408      slot_index = allocate_query_slot(svga, alloc_entry);
409   }
410
411   assert(slot_index != -1);
412   offset = slot_index * len + alloc_entry->start_offset;
413
414   return offset;
415}
416
417
418/**
419 * Deallocate memory slot allocated for the specified query
420 */
421static void
422deallocate_query(struct svga_context *svga,
423                 struct svga_query *sq)
424{
425   struct svga_qmem_alloc_entry *alloc_entry;
426   unsigned slot_index;
427   unsigned offset = sq->offset;
428
429   alloc_entry = svga->gb_query_map[sq->svga_type];
430
431   while (alloc_entry) {
432      if (offset >= alloc_entry->start_offset &&
433          offset < alloc_entry->start_offset + SVGA_QUERY_MEM_BLOCK_SIZE) {
434
435         /* The slot belongs to this memory block, deallocate it */
436         slot_index = (offset - alloc_entry->start_offset) /
437                      alloc_entry->query_size;
438         deallocate_query_slot(svga, alloc_entry, slot_index);
439         alloc_entry = NULL;
440      } else {
441         alloc_entry = alloc_entry->next;
442      }
443   }
444}
445
446
447/**
448 * Destroy the gb query object and all the related query structures
449 */
450static void
451destroy_gb_query_obj(struct svga_context *svga)
452{
453   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
454   unsigned i;
455
456   for (i = 0; i < SVGA3D_QUERYTYPE_MAX; i++) {
457      struct svga_qmem_alloc_entry *alloc_entry, *next;
458      alloc_entry = svga->gb_query_map[i];
459      while (alloc_entry) {
460         next = alloc_entry->next;
461         util_bitmask_destroy(alloc_entry->alloc_mask);
462         FREE(alloc_entry);
463         alloc_entry = next;
464      }
465      svga->gb_query_map[i] = NULL;
466   }
467
468   if (svga->gb_query)
469      sws->query_destroy(sws, svga->gb_query);
470   svga->gb_query = NULL;
471
472   util_bitmask_destroy(svga->gb_query_alloc_mask);
473}
474
475/**
476 * Define query and create the gb query object if it is not already created.
477 * There is only one gb query object per context which will be shared by
478 * queries of all types.
479 */
480static enum pipe_error
481define_query_vgpu10(struct svga_context *svga,
482                    struct svga_query *sq, int resultLen)
483{
484   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
485   int qlen;
486   enum pipe_error ret = PIPE_OK;
487
488   SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
489
490   if (svga->gb_query == NULL) {
491      /* Create a gb query object */
492      svga->gb_query = sws->query_create(sws, SVGA_QUERY_MEM_SIZE);
493      if (!svga->gb_query)
494         return PIPE_ERROR_OUT_OF_MEMORY;
495      svga->gb_query_len = SVGA_QUERY_MEM_SIZE;
496      memset (svga->gb_query_map, 0, sizeof(svga->gb_query_map));
497      svga->gb_query_alloc_mask = util_bitmask_create();
498
499      /* Bind the query object to the context */
500      if (svga->swc->query_bind(svga->swc, svga->gb_query,
501                                SVGA_QUERY_FLAG_SET) != PIPE_OK) {
502         svga_context_flush(svga, NULL);
503         svga->swc->query_bind(svga->swc, svga->gb_query,
504                               SVGA_QUERY_FLAG_SET);
505      }
506   }
507
508   sq->gb_query = svga->gb_query;
509
510   /* Allocate an integer ID for this query */
511   sq->id = util_bitmask_add(svga->query_id_bm);
512   if (sq->id == UTIL_BITMASK_INVALID_INDEX)
513      return PIPE_ERROR_OUT_OF_MEMORY;
514
515   /* Find a slot for this query in the gb object */
516   qlen = resultLen + sizeof(SVGA3dQueryState);
517   sq->offset = allocate_query(svga, sq->svga_type, qlen);
518   if (sq->offset == -1)
519      return PIPE_ERROR_OUT_OF_MEMORY;
520
521   SVGA_DBG(DEBUG_QUERY, "   query type=%d qid=0x%x offset=%d\n",
522            sq->svga_type, sq->id, sq->offset);
523
524   /**
525    * Send SVGA3D commands to define the query
526    */
527   ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
528   if (ret != PIPE_OK) {
529      svga_context_flush(svga, NULL);
530      ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
531   }
532   if (ret != PIPE_OK)
533      return PIPE_ERROR_OUT_OF_MEMORY;
534
535   ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
536   if (ret != PIPE_OK) {
537      svga_context_flush(svga, NULL);
538      ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
539   }
540   assert(ret == PIPE_OK);
541
542   ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
543   if (ret != PIPE_OK) {
544      svga_context_flush(svga, NULL);
545      ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
546   }
547   assert(ret == PIPE_OK);
548
549   return PIPE_OK;
550}
551
552static enum pipe_error
553destroy_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
554{
555   enum pipe_error ret;
556
557   ret = SVGA3D_vgpu10_DestroyQuery(svga->swc, sq->id);
558
559   /* Deallocate the memory slot allocated for this query */
560   deallocate_query(svga, sq);
561
562   return ret;
563}
564
565
566/**
567 * Rebind queryies to the context.
568 */
569static void
570rebind_vgpu10_query(struct svga_context *svga)
571{
572   if (svga->swc->query_bind(svga->swc, svga->gb_query,
573                             SVGA_QUERY_FLAG_REF) != PIPE_OK) {
574      svga_context_flush(svga, NULL);
575      svga->swc->query_bind(svga->swc, svga->gb_query,
576                            SVGA_QUERY_FLAG_REF);
577   }
578
579   svga->rebind.flags.query = FALSE;
580}
581
582
583static enum pipe_error
584begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
585{
586   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
587   enum pipe_error ret = PIPE_OK;
588   int status = 0;
589
590   sws->fence_reference(sws, &sq->fence, NULL);
591
592   /* Initialize the query state to NEW */
593   status = sws->query_init(sws, sq->gb_query, sq->offset, SVGA3D_QUERYSTATE_NEW);
594   if (status)
595      return PIPE_ERROR;
596
597   if (svga->rebind.flags.query) {
598      rebind_vgpu10_query(svga);
599   }
600
601   /* Send the BeginQuery command to the device */
602   ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
603   if (ret != PIPE_OK) {
604      svga_context_flush(svga, NULL);
605      ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
606   }
607   return ret;
608}
609
610static enum pipe_error
611end_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
612{
613   enum pipe_error ret = PIPE_OK;
614
615   if (svga->rebind.flags.query) {
616      rebind_vgpu10_query(svga);
617   }
618
619   ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
620   if (ret != PIPE_OK) {
621      svga_context_flush(svga, NULL);
622      ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
623   }
624
625   return ret;
626}
627
628static boolean
629get_query_result_vgpu10(struct svga_context *svga, struct svga_query *sq,
630                        boolean wait, void *result, int resultLen)
631{
632   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
633   SVGA3dQueryState queryState;
634
635   if (svga->rebind.flags.query) {
636      rebind_vgpu10_query(svga);
637   }
638
639   sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);
640
641   if (queryState != SVGA3D_QUERYSTATE_SUCCEEDED && !sq->fence) {
642      /* We don't have the query result yet, and the query hasn't been
643       * submitted.  We need to submit it now since the GL spec says
644       * "Querying the state for a given occlusion query forces that
645       * occlusion query to complete within a finite amount of time."
646       */
647      svga_context_flush(svga, &sq->fence);
648   }
649
650   if (queryState == SVGA3D_QUERYSTATE_PENDING ||
651       queryState == SVGA3D_QUERYSTATE_NEW) {
652      if (!wait)
653         return FALSE;
654      sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
655      sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);
656   }
657
658   assert(queryState == SVGA3D_QUERYSTATE_SUCCEEDED ||
659          queryState == SVGA3D_QUERYSTATE_FAILED);
660
661   return TRUE;
662}
663
664static struct pipe_query *
665svga_create_query(struct pipe_context *pipe,
666                  unsigned query_type,
667                  unsigned index)
668{
669   struct svga_context *svga = svga_context(pipe);
670   struct svga_query *sq;
671
672   assert(query_type < SVGA_QUERY_MAX);
673
674   sq = CALLOC_STRUCT(svga_query);
675   if (!sq)
676      goto fail;
677
678   /* Allocate an integer ID for the query */
679   sq->id = util_bitmask_add(svga->query_id_bm);
680   if (sq->id == UTIL_BITMASK_INVALID_INDEX)
681      goto fail;
682
683   SVGA_DBG(DEBUG_QUERY, "%s type=%d sq=0x%x id=%d\n", __FUNCTION__,
684            query_type, sq, sq->id);
685
686   switch (query_type) {
687   case PIPE_QUERY_OCCLUSION_COUNTER:
688      sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION;
689      if (svga_have_vgpu10(svga)) {
690         define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionQueryResult));
691
692         /**
693          * In OpenGL, occlusion counter query can be used in conditional
694          * rendering; however, in DX10, only OCCLUSION_PREDICATE query can
695          * be used for predication. Hence, we need to create an occlusion
696          * predicate query along with the occlusion counter query. So when
697          * the occlusion counter query is used for predication, the associated
698          * query of occlusion predicate type will be used
699          * in the SetPredication command.
700          */
701         sq->predicate = svga_create_query(pipe, PIPE_QUERY_OCCLUSION_PREDICATE, index);
702
703      } else {
704         define_query_vgpu9(svga, sq);
705      }
706      break;
707   case PIPE_QUERY_OCCLUSION_PREDICATE:
708      if (svga_have_vgpu10(svga)) {
709         sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE;
710         define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionPredicateQueryResult));
711      } else {
712         sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION;
713         define_query_vgpu9(svga, sq);
714      }
715      break;
716   case PIPE_QUERY_PRIMITIVES_GENERATED:
717   case PIPE_QUERY_PRIMITIVES_EMITTED:
718   case PIPE_QUERY_SO_STATISTICS:
719      assert(svga_have_vgpu10(svga));
720      sq->svga_type = SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS;
721      define_query_vgpu10(svga, sq,
722                          sizeof(SVGADXStreamOutStatisticsQueryResult));
723      break;
724   case PIPE_QUERY_TIMESTAMP:
725      assert(svga_have_vgpu10(svga));
726      sq->svga_type = SVGA3D_QUERYTYPE_TIMESTAMP;
727      define_query_vgpu10(svga, sq,
728                          sizeof(SVGADXTimestampQueryResult));
729      break;
730   case SVGA_QUERY_NUM_DRAW_CALLS:
731   case SVGA_QUERY_NUM_FALLBACKS:
732   case SVGA_QUERY_NUM_FLUSHES:
733   case SVGA_QUERY_NUM_VALIDATIONS:
734   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
735   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
736   case SVGA_QUERY_NUM_BYTES_UPLOADED:
737   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
738   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
739   case SVGA_QUERY_MEMORY_USED:
740   case SVGA_QUERY_NUM_SHADERS:
741   case SVGA_QUERY_NUM_RESOURCES:
742   case SVGA_QUERY_NUM_STATE_OBJECTS:
743   case SVGA_QUERY_NUM_SURFACE_VIEWS:
744   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
745   case SVGA_QUERY_NUM_READBACKS:
746   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
747   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
748   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
749   case SVGA_QUERY_NUM_CONST_UPDATES:
750      break;
751   case SVGA_QUERY_FLUSH_TIME:
752   case SVGA_QUERY_MAP_BUFFER_TIME:
753      /* These queries need os_time_get() */
754      svga->hud.uses_time = TRUE;
755      break;
756   default:
757      assert(!"unexpected query type in svga_create_query()");
758   }
759
760   sq->type = query_type;
761
762   return &sq->base;
763
764fail:
765   FREE(sq);
766   return NULL;
767}
768
769static void
770svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
771{
772   struct svga_context *svga = svga_context(pipe);
773   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
774   struct svga_query *sq;
775
776   if (!q) {
777      destroy_gb_query_obj(svga);
778      return;
779   }
780
781   sq = svga_query(q);
782
783   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
784            sq, sq->id);
785
786   switch (sq->type) {
787   case PIPE_QUERY_OCCLUSION_COUNTER:
788   case PIPE_QUERY_OCCLUSION_PREDICATE:
789      if (svga_have_vgpu10(svga)) {
790         /* make sure to also destroy any associated predicate query */
791         if (sq->predicate)
792            svga_destroy_query(pipe, sq->predicate);
793         destroy_query_vgpu10(svga, sq);
794      } else {
795         sws->buffer_destroy(sws, sq->hwbuf);
796      }
797      sws->fence_reference(sws, &sq->fence, NULL);
798      break;
799   case PIPE_QUERY_PRIMITIVES_GENERATED:
800   case PIPE_QUERY_PRIMITIVES_EMITTED:
801   case PIPE_QUERY_SO_STATISTICS:
802   case PIPE_QUERY_TIMESTAMP:
803      assert(svga_have_vgpu10(svga));
804      destroy_query_vgpu10(svga, sq);
805      sws->fence_reference(sws, &sq->fence, NULL);
806      break;
807   case SVGA_QUERY_NUM_DRAW_CALLS:
808   case SVGA_QUERY_NUM_FALLBACKS:
809   case SVGA_QUERY_NUM_FLUSHES:
810   case SVGA_QUERY_NUM_VALIDATIONS:
811   case SVGA_QUERY_MAP_BUFFER_TIME:
812   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
813   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
814   case SVGA_QUERY_NUM_BYTES_UPLOADED:
815   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
816   case SVGA_QUERY_FLUSH_TIME:
817   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
818   case SVGA_QUERY_MEMORY_USED:
819   case SVGA_QUERY_NUM_SHADERS:
820   case SVGA_QUERY_NUM_RESOURCES:
821   case SVGA_QUERY_NUM_STATE_OBJECTS:
822   case SVGA_QUERY_NUM_SURFACE_VIEWS:
823   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
824   case SVGA_QUERY_NUM_READBACKS:
825   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
826   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
827   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
828   case SVGA_QUERY_NUM_CONST_UPDATES:
829      /* nothing */
830      break;
831   default:
832      assert(!"svga: unexpected query type in svga_destroy_query()");
833   }
834
835   /* Free the query id */
836   util_bitmask_clear(svga->query_id_bm, sq->id);
837
838   FREE(sq);
839}
840
841
842static boolean
843svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
844{
845   struct svga_context *svga = svga_context(pipe);
846   struct svga_query *sq = svga_query(q);
847   enum pipe_error ret;
848
849   assert(sq);
850   assert(sq->type < SVGA_QUERY_MAX);
851
852   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
853            sq, sq->id);
854
855   /* Need to flush out buffered drawing commands so that they don't
856    * get counted in the query results.
857    */
858   svga_hwtnl_flush_retry(svga);
859
860   switch (sq->type) {
861   case PIPE_QUERY_OCCLUSION_COUNTER:
862   case PIPE_QUERY_OCCLUSION_PREDICATE:
863      if (svga_have_vgpu10(svga)) {
864         ret = begin_query_vgpu10(svga, sq);
865         /* also need to start the associated occlusion predicate query */
866         if (sq->predicate) {
867            enum pipe_error status;
868            status = begin_query_vgpu10(svga, svga_query(sq->predicate));
869            assert(status == PIPE_OK);
870            (void) status;
871         }
872      } else {
873         ret = begin_query_vgpu9(svga, sq);
874      }
875      assert(ret == PIPE_OK);
876      (void) ret;
877      break;
878   case PIPE_QUERY_PRIMITIVES_GENERATED:
879   case PIPE_QUERY_PRIMITIVES_EMITTED:
880   case PIPE_QUERY_SO_STATISTICS:
881   case PIPE_QUERY_TIMESTAMP:
882      assert(svga_have_vgpu10(svga));
883      ret = begin_query_vgpu10(svga, sq);
884      assert(ret == PIPE_OK);
885      break;
886   case SVGA_QUERY_NUM_DRAW_CALLS:
887      sq->begin_count = svga->hud.num_draw_calls;
888      break;
889   case SVGA_QUERY_NUM_FALLBACKS:
890      sq->begin_count = svga->hud.num_fallbacks;
891      break;
892   case SVGA_QUERY_NUM_FLUSHES:
893      sq->begin_count = svga->hud.num_flushes;
894      break;
895   case SVGA_QUERY_NUM_VALIDATIONS:
896      sq->begin_count = svga->hud.num_validations;
897      break;
898   case SVGA_QUERY_MAP_BUFFER_TIME:
899      sq->begin_count = svga->hud.map_buffer_time;
900      break;
901   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
902      sq->begin_count = svga->hud.num_buffers_mapped;
903      break;
904   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
905      sq->begin_count = svga->hud.num_textures_mapped;
906      break;
907   case SVGA_QUERY_NUM_BYTES_UPLOADED:
908      sq->begin_count = svga->hud.num_bytes_uploaded;
909      break;
910   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
911      sq->begin_count = svga->hud.command_buffer_size;
912      break;
913   case SVGA_QUERY_FLUSH_TIME:
914      sq->begin_count = svga->hud.flush_time;
915      break;
916   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
917      sq->begin_count = svga->hud.surface_write_flushes;
918      break;
919   case SVGA_QUERY_NUM_READBACKS:
920      sq->begin_count = svga->hud.num_readbacks;
921      break;
922   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
923      sq->begin_count = svga->hud.num_resource_updates;
924      break;
925   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
926      sq->begin_count = svga->hud.num_buffer_uploads;
927      break;
928   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
929      sq->begin_count = svga->hud.num_const_buf_updates;
930      break;
931   case SVGA_QUERY_NUM_CONST_UPDATES:
932      sq->begin_count = svga->hud.num_const_updates;
933      break;
934   case SVGA_QUERY_MEMORY_USED:
935   case SVGA_QUERY_NUM_SHADERS:
936   case SVGA_QUERY_NUM_RESOURCES:
937   case SVGA_QUERY_NUM_STATE_OBJECTS:
938   case SVGA_QUERY_NUM_SURFACE_VIEWS:
939   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
940      /* nothing */
941      break;
942   default:
943      assert(!"unexpected query type in svga_begin_query()");
944   }
945
946   svga->sq[sq->type] = sq;
947
948   return true;
949}
950
951
952static bool
953svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
954{
955   struct svga_context *svga = svga_context(pipe);
956   struct svga_query *sq = svga_query(q);
957   enum pipe_error ret;
958
959   assert(sq);
960   assert(sq->type < SVGA_QUERY_MAX);
961
962   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
963            sq, sq->id);
964
965   if (sq->type == PIPE_QUERY_TIMESTAMP && svga->sq[sq->type] != sq)
966      svga_begin_query(pipe, q);
967
968   svga_hwtnl_flush_retry(svga);
969
970   assert(svga->sq[sq->type] == sq);
971
972   switch (sq->type) {
973   case PIPE_QUERY_OCCLUSION_COUNTER:
974   case PIPE_QUERY_OCCLUSION_PREDICATE:
975      if (svga_have_vgpu10(svga)) {
976         ret = end_query_vgpu10(svga, sq);
977         /* also need to end the associated occlusion predicate query */
978         if (sq->predicate) {
979            enum pipe_error status;
980            status = end_query_vgpu10(svga, svga_query(sq->predicate));
981            assert(status == PIPE_OK);
982            (void) status;
983         }
984      } else {
985         ret = end_query_vgpu9(svga, sq);
986      }
987      assert(ret == PIPE_OK);
988      (void) ret;
989      break;
990   case PIPE_QUERY_PRIMITIVES_GENERATED:
991   case PIPE_QUERY_PRIMITIVES_EMITTED:
992   case PIPE_QUERY_SO_STATISTICS:
993   case PIPE_QUERY_TIMESTAMP:
994      assert(svga_have_vgpu10(svga));
995      ret = end_query_vgpu10(svga, sq);
996      assert(ret == PIPE_OK);
997      break;
998   case SVGA_QUERY_NUM_DRAW_CALLS:
999      sq->end_count = svga->hud.num_draw_calls;
1000      break;
1001   case SVGA_QUERY_NUM_FALLBACKS:
1002      sq->end_count = svga->hud.num_fallbacks;
1003      break;
1004   case SVGA_QUERY_NUM_FLUSHES:
1005      sq->end_count = svga->hud.num_flushes;
1006      break;
1007   case SVGA_QUERY_NUM_VALIDATIONS:
1008      sq->end_count = svga->hud.num_validations;
1009      break;
1010   case SVGA_QUERY_MAP_BUFFER_TIME:
1011      sq->end_count = svga->hud.map_buffer_time;
1012      break;
1013   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
1014      sq->end_count = svga->hud.num_buffers_mapped;
1015      break;
1016   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
1017      sq->end_count = svga->hud.num_textures_mapped;
1018      break;
1019   case SVGA_QUERY_NUM_BYTES_UPLOADED:
1020      sq->end_count = svga->hud.num_bytes_uploaded;
1021      break;
1022   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
1023      sq->end_count = svga->hud.command_buffer_size;
1024      break;
1025   case SVGA_QUERY_FLUSH_TIME:
1026      sq->end_count = svga->hud.flush_time;
1027      break;
1028   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
1029      sq->end_count = svga->hud.surface_write_flushes;
1030      break;
1031   case SVGA_QUERY_NUM_READBACKS:
1032      sq->end_count = svga->hud.num_readbacks;
1033      break;
1034   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
1035      sq->end_count = svga->hud.num_resource_updates;
1036      break;
1037   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
1038      sq->end_count = svga->hud.num_buffer_uploads;
1039      break;
1040   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
1041      sq->end_count = svga->hud.num_const_buf_updates;
1042      break;
1043   case SVGA_QUERY_NUM_CONST_UPDATES:
1044      sq->end_count = svga->hud.num_const_updates;
1045      break;
1046   case SVGA_QUERY_MEMORY_USED:
1047   case SVGA_QUERY_NUM_SHADERS:
1048   case SVGA_QUERY_NUM_RESOURCES:
1049   case SVGA_QUERY_NUM_STATE_OBJECTS:
1050   case SVGA_QUERY_NUM_SURFACE_VIEWS:
1051   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
1052      /* nothing */
1053      break;
1054   default:
1055      assert(!"unexpected query type in svga_end_query()");
1056   }
1057   svga->sq[sq->type] = NULL;
1058   return true;
1059}
1060
1061
1062static boolean
1063svga_get_query_result(struct pipe_context *pipe,
1064                      struct pipe_query *q,
1065                      boolean wait,
1066                      union pipe_query_result *vresult)
1067{
1068   struct svga_screen *svgascreen = svga_screen(pipe->screen);
1069   struct svga_context *svga = svga_context(pipe);
1070   struct svga_query *sq = svga_query(q);
1071   uint64_t *result = (uint64_t *)vresult;
1072   boolean ret = TRUE;
1073
1074   assert(sq);
1075
1076   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d wait: %d\n",
1077            __FUNCTION__, sq, sq->id, wait);
1078
1079   switch (sq->type) {
1080   case PIPE_QUERY_OCCLUSION_COUNTER:
1081      if (svga_have_vgpu10(svga)) {
1082         SVGADXOcclusionQueryResult occResult;
1083         ret = get_query_result_vgpu10(svga, sq, wait,
1084                                       (void *)&occResult, sizeof(occResult));
1085         *result = (uint64_t)occResult.samplesRendered;
1086      } else {
1087         ret = get_query_result_vgpu9(svga, sq, wait, result);
1088      }
1089      break;
1090   case PIPE_QUERY_OCCLUSION_PREDICATE: {
1091      if (svga_have_vgpu10(svga)) {
1092         SVGADXOcclusionPredicateQueryResult occResult;
1093         ret = get_query_result_vgpu10(svga, sq, wait,
1094                                       (void *)&occResult, sizeof(occResult));
1095         vresult->b = occResult.anySamplesRendered != 0;
1096      } else {
1097         uint64_t count = 0;
1098         ret = get_query_result_vgpu9(svga, sq, wait, &count);
1099         vresult->b = count != 0;
1100      }
1101      break;
1102   }
1103   case PIPE_QUERY_SO_STATISTICS: {
1104      SVGADXStreamOutStatisticsQueryResult sResult;
1105      struct pipe_query_data_so_statistics *pResult =
1106         (struct pipe_query_data_so_statistics *)vresult;
1107
1108      assert(svga_have_vgpu10(svga));
1109      ret = get_query_result_vgpu10(svga, sq, wait,
1110                                    (void *)&sResult, sizeof(sResult));
1111      pResult->num_primitives_written = sResult.numPrimitivesWritten;
1112      pResult->primitives_storage_needed = sResult.numPrimitivesRequired;
1113      break;
1114   }
1115   case PIPE_QUERY_TIMESTAMP: {
1116      SVGADXTimestampQueryResult sResult;
1117
1118      assert(svga_have_vgpu10(svga));
1119      ret = get_query_result_vgpu10(svga, sq, wait,
1120                                    (void *)&sResult, sizeof(sResult));
1121      *result = (uint64_t)sResult.timestamp;
1122      break;
1123   }
1124   case PIPE_QUERY_PRIMITIVES_GENERATED: {
1125      SVGADXStreamOutStatisticsQueryResult sResult;
1126
1127      assert(svga_have_vgpu10(svga));
1128      ret = get_query_result_vgpu10(svga, sq, wait,
1129                                    (void *)&sResult, sizeof sResult);
1130      *result = (uint64_t)sResult.numPrimitivesRequired;
1131      break;
1132   }
1133   case PIPE_QUERY_PRIMITIVES_EMITTED: {
1134      SVGADXStreamOutStatisticsQueryResult sResult;
1135
1136      assert(svga_have_vgpu10(svga));
1137      ret = get_query_result_vgpu10(svga, sq, wait,
1138                                    (void *)&sResult, sizeof sResult);
1139      *result = (uint64_t)sResult.numPrimitivesWritten;
1140      break;
1141   }
1142   /* These are per-frame counters */
1143   case SVGA_QUERY_NUM_DRAW_CALLS:
1144   case SVGA_QUERY_NUM_FALLBACKS:
1145   case SVGA_QUERY_NUM_FLUSHES:
1146   case SVGA_QUERY_NUM_VALIDATIONS:
1147   case SVGA_QUERY_MAP_BUFFER_TIME:
1148   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
1149   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
1150   case SVGA_QUERY_NUM_BYTES_UPLOADED:
1151   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
1152   case SVGA_QUERY_FLUSH_TIME:
1153   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
1154   case SVGA_QUERY_NUM_READBACKS:
1155   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
1156   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
1157   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
1158   case SVGA_QUERY_NUM_CONST_UPDATES:
1159      vresult->u64 = sq->end_count - sq->begin_count;
1160      break;
1161   /* These are running total counters */
1162   case SVGA_QUERY_MEMORY_USED:
1163      vresult->u64 = svgascreen->hud.total_resource_bytes;
1164      break;
1165   case SVGA_QUERY_NUM_SHADERS:
1166      vresult->u64 = svga->hud.num_shaders;
1167      break;
1168   case SVGA_QUERY_NUM_RESOURCES:
1169      vresult->u64 = svgascreen->hud.num_resources;
1170      break;
1171   case SVGA_QUERY_NUM_STATE_OBJECTS:
1172      vresult->u64 = (svga->hud.num_blend_objects +
1173                      svga->hud.num_depthstencil_objects +
1174                      svga->hud.num_rasterizer_objects +
1175                      svga->hud.num_sampler_objects +
1176                      svga->hud.num_samplerview_objects +
1177                      svga->hud.num_vertexelement_objects);
1178      break;
1179   case SVGA_QUERY_NUM_SURFACE_VIEWS:
1180      vresult->u64 = svga->hud.num_surface_views;
1181      break;
1182   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
1183      vresult->u64 = svga->hud.num_generate_mipmap;
1184      break;
1185   default:
1186      assert(!"unexpected query type in svga_get_query_result");
1187   }
1188
1189   SVGA_DBG(DEBUG_QUERY, "%s result %d\n", __FUNCTION__, *((uint64_t *)vresult));
1190
1191   return ret;
1192}
1193
1194static void
1195svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
1196                      boolean condition, uint mode)
1197{
1198   struct svga_context *svga = svga_context(pipe);
1199   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
1200   struct svga_query *sq = svga_query(q);
1201   SVGA3dQueryId queryId;
1202   enum pipe_error ret;
1203
1204   SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
1205
1206   assert(svga_have_vgpu10(svga));
1207   if (sq == NULL) {
1208      queryId = SVGA3D_INVALID_ID;
1209   }
1210   else {
1211      assert(sq->svga_type == SVGA3D_QUERYTYPE_OCCLUSION ||
1212             sq->svga_type == SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE);
1213
1214      if (sq->svga_type == SVGA3D_QUERYTYPE_OCCLUSION) {
1215         assert(sq->predicate);
1216         /**
1217          * For conditional rendering, make sure to use the associated
1218          * predicate query.
1219          */
1220         sq = svga_query(sq->predicate);
1221      }
1222      queryId = sq->id;
1223
1224      if ((mode == PIPE_RENDER_COND_WAIT ||
1225           mode == PIPE_RENDER_COND_BY_REGION_WAIT) && sq->fence) {
1226         sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
1227      }
1228   }
1229   /*
1230    * if the kernel module doesn't support the predication command,
1231    * we'll just render unconditionally.
1232    * This is probably acceptable for the typical case of occlusion culling.
1233    */
1234   if (sws->have_set_predication_cmd) {
1235      ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
1236                                         (uint32) condition);
1237      if (ret != PIPE_OK) {
1238         svga_context_flush(svga, NULL);
1239         ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
1240                                            (uint32) condition);
1241      }
1242      svga->pred.query_id = queryId;
1243      svga->pred.cond = condition;
1244   }
1245
1246   svga->render_condition = (sq != NULL);
1247}
1248
1249
1250/*
1251 * This function is a workaround because we lack the ability to query
1252 * renderer's time synchornously.
1253 */
1254static uint64_t
1255svga_get_timestamp(struct pipe_context *pipe)
1256{
1257   struct pipe_query *q = svga_create_query(pipe, PIPE_QUERY_TIMESTAMP, 0);
1258   union pipe_query_result result;
1259
1260   svga_begin_query(pipe, q);
1261   svga_end_query(pipe,q);
1262   svga_get_query_result(pipe, q, TRUE, &result);
1263   svga_destroy_query(pipe, q);
1264
1265   return result.u64;
1266}
1267
1268
1269static void
1270svga_set_active_query_state(struct pipe_context *pipe, boolean enable)
1271{
1272}
1273
1274
1275void
1276svga_init_query_functions(struct svga_context *svga)
1277{
1278   svga->pipe.create_query = svga_create_query;
1279   svga->pipe.destroy_query = svga_destroy_query;
1280   svga->pipe.begin_query = svga_begin_query;
1281   svga->pipe.end_query = svga_end_query;
1282   svga->pipe.get_query_result = svga_get_query_result;
1283   svga->pipe.set_active_query_state = svga_set_active_query_state;
1284   svga->pipe.render_condition = svga_render_condition;
1285   svga->pipe.get_timestamp = svga_get_timestamp;
1286}
1287