/**********************************************************
 * Copyright 2008-2015 VMware, Inc.  All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 **********************************************************/

#include "pipe/p_state.h"
#include "pipe/p_context.h"

#include "util/u_bitmask.h"
#include "util/u_memory.h"

#include "svga_cmd.h"
#include "svga_context.h"
#include "svga_screen.h"
#include "svga_resource_buffer.h"
#include "svga_winsys.h"
#include "svga_debug.h"


/* Fixme: want a public base class for all pipe structs, even if there
 * isn't much in them.
 */
struct pipe_query {
   int dummy;
};

struct svga_query {
   struct pipe_query base;
   unsigned type;                  /**< PIPE_QUERY_x or SVGA_QUERY_x */
   SVGA3dQueryType svga_type;      /**< SVGA3D_QUERYTYPE_x or unused */

   unsigned id;                    /** Per-context query identifier */

   struct pipe_fence_handle *fence;

   /** For PIPE_QUERY_OCCLUSION_COUNTER / SVGA3D_QUERYTYPE_OCCLUSION */

   /* For VGPU9 */
   struct svga_winsys_buffer *hwbuf;
   volatile SVGA3dQueryResult *queryResult;

   /** For VGPU10 */
   struct svga_winsys_gb_query *gb_query;
   SVGA3dDXQueryFlags flags;
   unsigned offset;                /**< offset to the gb_query memory */
   struct pipe_query *predicate;   /** The associated query that can be used for predicate */

   /** For non-GPU SVGA_QUERY_x queries */
   uint64_t begin_count, end_count;
};


/** cast wrapper */
static inline struct svga_query *
svga_query(struct pipe_query *q)
{
   return (struct svga_query *)q;
}

/**
 * VGPU9
 */

static boolean
svga_get_query_result(struct pipe_context *pipe,
                      struct pipe_query *q,
                      boolean wait,
                      union pipe_query_result *result);

static enum pipe_error
define_query_vgpu9(struct svga_context *svga,
                   struct svga_query *sq)
{
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;

   sq->hwbuf = svga_winsys_buffer_create(svga, 1,
                                         SVGA_BUFFER_USAGE_PINNED,
                                         sizeof *sq->queryResult);
   if (!sq->hwbuf)
      return PIPE_ERROR_OUT_OF_MEMORY;

   sq->queryResult = (SVGA3dQueryResult *)
                     sws->buffer_map(sws, sq->hwbuf, PIPE_TRANSFER_WRITE);
   if (!sq->queryResult) {
      sws->buffer_destroy(sws, sq->hwbuf);
      return PIPE_ERROR_OUT_OF_MEMORY;
   }

   sq->queryResult->totalSize = sizeof *sq->queryResult;
   sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;

   /* We request the buffer to be pinned and assume it is always mapped.
    * The reason is that we don't want to wait for fences when checking the
    * query status.
    */
   sws->buffer_unmap(sws, sq->hwbuf);

   return PIPE_OK;
}

static enum pipe_error
begin_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
{
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   enum pipe_error ret = PIPE_OK;

   if (sq->queryResult->state == SVGA3D_QUERYSTATE_PENDING) {
      /* The application doesn't care for the pending query result.
       * We cannot let go of the existing buffer and just get a new one
       * because its storage may be reused for other purposes and clobbered
       * by the host when it determines the query result.  So the only
       * option here is to wait for the existing query's result -- not a
       * big deal, given that no sane application would do this.
       */
       uint64_t result;
       svga_get_query_result(&svga->pipe, &sq->base, TRUE, (void*)&result);
       assert(sq->queryResult->state != SVGA3D_QUERYSTATE_PENDING);
   }

   sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
   sws->fence_reference(sws, &sq->fence, NULL);

   ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type);
   }
   return ret;
}

static enum pipe_error
end_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
{
   enum pipe_error ret = PIPE_OK;

   /* Set to PENDING before sending EndQuery. */
   sq->queryResult->state = SVGA3D_QUERYSTATE_PENDING;

   ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf);
   }
   return ret;
}

static boolean
get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
                       boolean wait, uint64_t *result)
{
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   enum pipe_error ret;
   SVGA3dQueryState state;

   if (!sq->fence) {
      /* The query status won't be updated by the host unless
       * SVGA_3D_CMD_WAIT_FOR_QUERY is emitted. Unfortunately this will cause
       * a synchronous wait on the host.
       */
      ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf);
      if (ret != PIPE_OK) {
         svga_context_flush(svga, NULL);
         ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf);
      }
      assert (ret == PIPE_OK);
      svga_context_flush(svga, &sq->fence);
      assert(sq->fence);
   }

   state = sq->queryResult->state;
   if (state == SVGA3D_QUERYSTATE_PENDING) {
      if (!wait)
         return FALSE;
      sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
                        SVGA_FENCE_FLAG_QUERY);
      state = sq->queryResult->state;
   }

   assert(state == SVGA3D_QUERYSTATE_SUCCEEDED ||
          state == SVGA3D_QUERYSTATE_FAILED);

   *result = (uint64_t)sq->queryResult->result32;
   return TRUE;
}


/**
 * VGPU10
 *
 * There is one query mob allocated for each context to be shared by all
 * query types. The mob is used to hold queries's state and result. Since
 * each query result type is of different length, to ease the query allocation
 * management, the mob is divided into memory blocks. Each memory block
 * will hold queries of the same type. Multiple memory blocks can be allocated
 * for a particular query type.
 *
 * Currently each memory block is of 184 bytes. We support up to 128
 * memory blocks. The query memory size is arbitrary right now.
 * Each occlusion query takes about 8 bytes. One memory block can accomodate
 * 23 occlusion queries. 128 of those blocks can support up to 2944 occlusion
 * queries. That seems reasonable for now. If we think this limit is
 * not enough, we can increase the limit or try to grow the mob in runtime.
 * Note, SVGA device does not impose one mob per context for queries,
 * we could allocate multiple mobs for queries; however, wddm KMD does not
 * currently support that.
 *
 * Also note that the GL guest driver does not issue any of the
 * following commands: DXMoveQuery, DXBindAllQuery & DXReadbackAllQuery.
 */
#define SVGA_QUERY_MEM_BLOCK_SIZE    (sizeof(SVGADXQueryResultUnion) * 2)
#define SVGA_QUERY_MEM_SIZE          (128 * SVGA_QUERY_MEM_BLOCK_SIZE)

struct svga_qmem_alloc_entry
{
   unsigned start_offset;               /* start offset of the memory block */
   unsigned block_index;                /* block index of the memory block */
   unsigned query_size;                 /* query size in this memory block */
   unsigned nquery;                     /* number of queries allocated */
   struct util_bitmask *alloc_mask;     /* allocation mask */
   struct svga_qmem_alloc_entry *next;  /* next memory block */
};


/**
 * Allocate a memory block from the query object memory
 * \return -1 if out of memory, else index of the query memory block
 */
static int
allocate_query_block(struct svga_context *svga)
{
   int index;
   unsigned offset;

   /* Find the next available query block */
   index = util_bitmask_add(svga->gb_query_alloc_mask);

   if (index == UTIL_BITMASK_INVALID_INDEX)
      return -1;

   offset = index * SVGA_QUERY_MEM_BLOCK_SIZE;
   if (offset >= svga->gb_query_len) {
      unsigned i;

      /**
       * All the memory blocks are allocated, lets see if there is
       * any empty memory block around that can be freed up.
       */
      index = -1;
      for (i = 0; i < SVGA3D_QUERYTYPE_MAX && index == -1; i++) {
         struct svga_qmem_alloc_entry *alloc_entry;
         struct svga_qmem_alloc_entry *prev_alloc_entry = NULL;

         alloc_entry = svga->gb_query_map[i];
         while (alloc_entry && index == -1) {
            if (alloc_entry->nquery == 0) {
               /* This memory block is empty, it can be recycled. */
               if (prev_alloc_entry) {
                  prev_alloc_entry->next = alloc_entry->next;
               } else {
                  svga->gb_query_map[i] = alloc_entry->next;
               }
               index = alloc_entry->block_index;
            } else {
               prev_alloc_entry = alloc_entry;
               alloc_entry = alloc_entry->next;
            }
         }
      }
   }

   return index;
}

/**
 * Allocate a slot in the specified memory block.
 * All slots in this memory block are of the same size.
 *
 * \return -1 if out of memory, else index of the query slot
 */
static int
allocate_query_slot(struct svga_context *svga,
                    struct svga_qmem_alloc_entry *alloc)
{
   int index;
   unsigned offset;

   /* Find the next available slot */
   index = util_bitmask_add(alloc->alloc_mask);

   if (index == UTIL_BITMASK_INVALID_INDEX)
      return -1;

   offset = index * alloc->query_size;
   if (offset >= SVGA_QUERY_MEM_BLOCK_SIZE)
      return -1;

   alloc->nquery++;

   return index;
}

/**
 * Deallocate the specified slot in the memory block.
 * If all slots are freed up, then deallocate the memory block
 * as well, so it can be allocated for other query type
 */
static void
deallocate_query_slot(struct svga_context *svga,
                      struct svga_qmem_alloc_entry *alloc,
                      unsigned index)
{
   assert(index != UTIL_BITMASK_INVALID_INDEX);

   util_bitmask_clear(alloc->alloc_mask, index);
   alloc->nquery--;

   /**
    * Don't worry about deallocating the empty memory block here.
    * The empty memory block will be recycled when no more memory block
    * can be allocated.
    */
}

static struct svga_qmem_alloc_entry *
allocate_query_block_entry(struct svga_context *svga,
                           unsigned len)
{
   struct svga_qmem_alloc_entry *alloc_entry;
   int block_index = -1;

   block_index = allocate_query_block(svga);
   if (block_index == -1)
      return NULL;
   alloc_entry = CALLOC_STRUCT(svga_qmem_alloc_entry);
   if (!alloc_entry)
      return NULL;

   alloc_entry->block_index = block_index;
   alloc_entry->start_offset = block_index * SVGA_QUERY_MEM_BLOCK_SIZE;
   alloc_entry->nquery = 0;
   alloc_entry->alloc_mask = util_bitmask_create();
   alloc_entry->next = NULL;
   alloc_entry->query_size = len;

   return alloc_entry;
}

/**
 * Allocate a memory slot for a query of the specified type.
 * It will first search through the memory blocks that are allocated
 * for the query type. If no memory slot is available, it will try
 * to allocate another memory block within the query object memory for
 * this query type.
 */
static int
allocate_query(struct svga_context *svga,
               SVGA3dQueryType type,
               unsigned len)
{
   struct svga_qmem_alloc_entry *alloc_entry;
   int slot_index = -1;
   unsigned offset;

   assert(type < SVGA3D_QUERYTYPE_MAX);

   alloc_entry = svga->gb_query_map[type];

   if (!alloc_entry) {
      /**
       * No query memory block has been allocated for this query type,
       * allocate one now
       */
      alloc_entry = allocate_query_block_entry(svga, len);
      if (!alloc_entry)
         return -1;
      svga->gb_query_map[type] = alloc_entry;
   }

   /* Allocate a slot within the memory block allocated for this query type */
   slot_index = allocate_query_slot(svga, alloc_entry);

   if (slot_index == -1) {
      /* This query memory block is full, allocate another one */
      alloc_entry = allocate_query_block_entry(svga, len);
      if (!alloc_entry)
         return -1;
      alloc_entry->next = svga->gb_query_map[type];
      svga->gb_query_map[type] = alloc_entry;
      slot_index = allocate_query_slot(svga, alloc_entry);
   }

   assert(slot_index != -1);
   offset = slot_index * len + alloc_entry->start_offset;

   return offset;
}


/**
 * Deallocate memory slot allocated for the specified query
 */
static void
deallocate_query(struct svga_context *svga,
                 struct svga_query *sq)
{
   struct svga_qmem_alloc_entry *alloc_entry;
   unsigned slot_index;
   unsigned offset = sq->offset;

   alloc_entry = svga->gb_query_map[sq->svga_type];

   while (alloc_entry) {
      if (offset >= alloc_entry->start_offset &&
          offset < alloc_entry->start_offset + SVGA_QUERY_MEM_BLOCK_SIZE) {

         /* The slot belongs to this memory block, deallocate it */
         slot_index = (offset - alloc_entry->start_offset) /
                      alloc_entry->query_size;
         deallocate_query_slot(svga, alloc_entry, slot_index);
         alloc_entry = NULL;
      } else {
         alloc_entry = alloc_entry->next;
      }
   }
}


/**
 * Destroy the gb query object and all the related query structures
 */
static void
destroy_gb_query_obj(struct svga_context *svga)
{
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   unsigned i;

   for (i = 0; i < SVGA3D_QUERYTYPE_MAX; i++) {
      struct svga_qmem_alloc_entry *alloc_entry, *next;
      alloc_entry = svga->gb_query_map[i];
      while (alloc_entry) {
         next = alloc_entry->next;
         util_bitmask_destroy(alloc_entry->alloc_mask);
         FREE(alloc_entry);
         alloc_entry = next;
      }
      svga->gb_query_map[i] = NULL;
   }

   if (svga->gb_query)
      sws->query_destroy(sws, svga->gb_query);
   svga->gb_query = NULL;

   util_bitmask_destroy(svga->gb_query_alloc_mask);
}

/**
 * Define query and create the gb query object if it is not already created.
 * There is only one gb query object per context which will be shared by
 * queries of all types.
 */
static enum pipe_error
define_query_vgpu10(struct svga_context *svga,
                    struct svga_query *sq, int resultLen)
{
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   int qlen;
   enum pipe_error ret = PIPE_OK;

   SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);

   if (svga->gb_query == NULL) {
      /* Create a gb query object */
      svga->gb_query = sws->query_create(sws, SVGA_QUERY_MEM_SIZE);
      if (!svga->gb_query)
         return PIPE_ERROR_OUT_OF_MEMORY;
      svga->gb_query_len = SVGA_QUERY_MEM_SIZE;
      memset (svga->gb_query_map, 0, sizeof(svga->gb_query_map));
      svga->gb_query_alloc_mask = util_bitmask_create();

      /* Bind the query object to the context */
      if (svga->swc->query_bind(svga->swc, svga->gb_query,
                                SVGA_QUERY_FLAG_SET) != PIPE_OK) {
         svga_context_flush(svga, NULL);
         svga->swc->query_bind(svga->swc, svga->gb_query,
                               SVGA_QUERY_FLAG_SET);
      }
   }

   sq->gb_query = svga->gb_query;

   /* Allocate an integer ID for this query */
   sq->id = util_bitmask_add(svga->query_id_bm);
   if (sq->id == UTIL_BITMASK_INVALID_INDEX)
      return PIPE_ERROR_OUT_OF_MEMORY;

   /* Find a slot for this query in the gb object */
   qlen = resultLen + sizeof(SVGA3dQueryState);
   sq->offset = allocate_query(svga, sq->svga_type, qlen);
   if (sq->offset == -1)
      return PIPE_ERROR_OUT_OF_MEMORY;

   SVGA_DBG(DEBUG_QUERY, "   query type=%d qid=0x%x offset=%d\n",
            sq->svga_type, sq->id, sq->offset);

   /**
    * Send SVGA3D commands to define the query
    */
   ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
   }
   if (ret != PIPE_OK)
      return PIPE_ERROR_OUT_OF_MEMORY;

   ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
   }
   assert(ret == PIPE_OK);

   ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
   }
   assert(ret == PIPE_OK);

   return PIPE_OK;
}

static enum pipe_error
destroy_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
{
   enum pipe_error ret;

   ret = SVGA3D_vgpu10_DestroyQuery(svga->swc, sq->id);

   /* Deallocate the memory slot allocated for this query */
   deallocate_query(svga, sq);

   return ret;
}


/**
 * Rebind queryies to the context.
 */
static void
rebind_vgpu10_query(struct svga_context *svga)
{
   if (svga->swc->query_bind(svga->swc, svga->gb_query,
                             SVGA_QUERY_FLAG_REF) != PIPE_OK) {
      svga_context_flush(svga, NULL);
      svga->swc->query_bind(svga->swc, svga->gb_query,
                            SVGA_QUERY_FLAG_REF);
   }

   svga->rebind.flags.query = FALSE;
}


static enum pipe_error
begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
{
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   enum pipe_error ret = PIPE_OK;
   int status = 0;

   sws->fence_reference(sws, &sq->fence, NULL);

   /* Initialize the query state to NEW */
   status = sws->query_init(sws, sq->gb_query, sq->offset, SVGA3D_QUERYSTATE_NEW);
   if (status)
      return PIPE_ERROR;

   if (svga->rebind.flags.query) {
      rebind_vgpu10_query(svga);
   }

   /* Send the BeginQuery command to the device */
   ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
   }
   return ret;
}

static enum pipe_error
end_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
{
   enum pipe_error ret = PIPE_OK;

   if (svga->rebind.flags.query) {
      rebind_vgpu10_query(svga);
   }

   ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
   }

   return ret;
}

static boolean
get_query_result_vgpu10(struct svga_context *svga, struct svga_query *sq,
                        boolean wait, void *result, int resultLen)
{
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   SVGA3dQueryState queryState;

   if (svga->rebind.flags.query) {
      rebind_vgpu10_query(svga);
   }

   sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);

   if (queryState != SVGA3D_QUERYSTATE_SUCCEEDED && !sq->fence) {
      /* We don't have the query result yet, and the query hasn't been
       * submitted.  We need to submit it now since the GL spec says
       * "Querying the state for a given occlusion query forces that
       * occlusion query to complete within a finite amount of time."
       */
      svga_context_flush(svga, &sq->fence);
   }

   if (queryState == SVGA3D_QUERYSTATE_PENDING ||
       queryState == SVGA3D_QUERYSTATE_NEW) {
      if (!wait)
         return FALSE;
      sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
                        SVGA_FENCE_FLAG_QUERY);
      sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);
   }

   assert(queryState == SVGA3D_QUERYSTATE_SUCCEEDED ||
          queryState == SVGA3D_QUERYSTATE_FAILED);

   return TRUE;
}

static struct pipe_query *
svga_create_query(struct pipe_context *pipe,
                  unsigned query_type,
                  unsigned index)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_query *sq;

   assert(query_type < SVGA_QUERY_MAX);

   sq = CALLOC_STRUCT(svga_query);
   if (!sq)
      goto fail;

   /* Allocate an integer ID for the query */
   sq->id = util_bitmask_add(svga->query_id_bm);
   if (sq->id == UTIL_BITMASK_INVALID_INDEX)
      goto fail;

   SVGA_DBG(DEBUG_QUERY, "%s type=%d sq=0x%x id=%d\n", __FUNCTION__,
            query_type, sq, sq->id);

   switch (query_type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
      sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION;
      if (svga_have_vgpu10(svga)) {
         define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionQueryResult));

         /**
          * In OpenGL, occlusion counter query can be used in conditional
          * rendering; however, in DX10, only OCCLUSION_PREDICATE query can
          * be used for predication. Hence, we need to create an occlusion
          * predicate query along with the occlusion counter query. So when
          * the occlusion counter query is used for predication, the associated
          * query of occlusion predicate type will be used
          * in the SetPredication command.
          */
         sq->predicate = svga_create_query(pipe, PIPE_QUERY_OCCLUSION_PREDICATE, index);

      } else {
         define_query_vgpu9(svga, sq);
      }
      break;
   case PIPE_QUERY_OCCLUSION_PREDICATE:
   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
      if (svga_have_vgpu10(svga)) {
         sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE;
         define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionPredicateQueryResult));
      } else {
         sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION;
         define_query_vgpu9(svga, sq);
      }
      break;
   case PIPE_QUERY_PRIMITIVES_GENERATED:
   case PIPE_QUERY_PRIMITIVES_EMITTED:
   case PIPE_QUERY_SO_STATISTICS:
      assert(svga_have_vgpu10(svga));
      sq->svga_type = SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS;
      define_query_vgpu10(svga, sq,
                          sizeof(SVGADXStreamOutStatisticsQueryResult));
      break;
   case PIPE_QUERY_TIMESTAMP:
      assert(svga_have_vgpu10(svga));
      sq->svga_type = SVGA3D_QUERYTYPE_TIMESTAMP;
      define_query_vgpu10(svga, sq,
                          sizeof(SVGADXTimestampQueryResult));
      break;
   case SVGA_QUERY_NUM_DRAW_CALLS:
   case SVGA_QUERY_NUM_FALLBACKS:
   case SVGA_QUERY_NUM_FLUSHES:
   case SVGA_QUERY_NUM_VALIDATIONS:
   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
   case SVGA_QUERY_NUM_BYTES_UPLOADED:
   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
   case SVGA_QUERY_MEMORY_USED:
   case SVGA_QUERY_NUM_SHADERS:
   case SVGA_QUERY_NUM_RESOURCES:
   case SVGA_QUERY_NUM_STATE_OBJECTS:
   case SVGA_QUERY_NUM_SURFACE_VIEWS:
   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
   case SVGA_QUERY_NUM_READBACKS:
   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
   case SVGA_QUERY_NUM_CONST_UPDATES:
   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
      break;
   case SVGA_QUERY_FLUSH_TIME:
   case SVGA_QUERY_MAP_BUFFER_TIME:
      /* These queries need os_time_get() */
      svga->hud.uses_time = TRUE;
      break;
   default:
      assert(!"unexpected query type in svga_create_query()");
   }

   sq->type = query_type;

   return &sq->base;

fail:
   FREE(sq);
   return NULL;
}

static void
svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   struct svga_query *sq;

   if (!q) {
      destroy_gb_query_obj(svga);
      return;
   }

   sq = svga_query(q);

   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
            sq, sq->id);

   switch (sq->type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
   case PIPE_QUERY_OCCLUSION_PREDICATE:
   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
      if (svga_have_vgpu10(svga)) {
         /* make sure to also destroy any associated predicate query */
         if (sq->predicate)
            svga_destroy_query(pipe, sq->predicate);
         destroy_query_vgpu10(svga, sq);
      } else {
         sws->buffer_destroy(sws, sq->hwbuf);
      }
      sws->fence_reference(sws, &sq->fence, NULL);
      break;
   case PIPE_QUERY_PRIMITIVES_GENERATED:
   case PIPE_QUERY_PRIMITIVES_EMITTED:
   case PIPE_QUERY_SO_STATISTICS:
   case PIPE_QUERY_TIMESTAMP:
      assert(svga_have_vgpu10(svga));
      destroy_query_vgpu10(svga, sq);
      sws->fence_reference(sws, &sq->fence, NULL);
      break;
   case SVGA_QUERY_NUM_DRAW_CALLS:
   case SVGA_QUERY_NUM_FALLBACKS:
   case SVGA_QUERY_NUM_FLUSHES:
   case SVGA_QUERY_NUM_VALIDATIONS:
   case SVGA_QUERY_MAP_BUFFER_TIME:
   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
   case SVGA_QUERY_NUM_BYTES_UPLOADED:
   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
   case SVGA_QUERY_FLUSH_TIME:
   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
   case SVGA_QUERY_MEMORY_USED:
   case SVGA_QUERY_NUM_SHADERS:
   case SVGA_QUERY_NUM_RESOURCES:
   case SVGA_QUERY_NUM_STATE_OBJECTS:
   case SVGA_QUERY_NUM_SURFACE_VIEWS:
   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
   case SVGA_QUERY_NUM_READBACKS:
   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
   case SVGA_QUERY_NUM_CONST_UPDATES:
   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
      /* nothing */
      break;
   default:
      assert(!"svga: unexpected query type in svga_destroy_query()");
   }

   /* Free the query id */
   util_bitmask_clear(svga->query_id_bm, sq->id);

   FREE(sq);
}


static boolean
svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_query *sq = svga_query(q);
   enum pipe_error ret;

   assert(sq);
   assert(sq->type < SVGA_QUERY_MAX);

   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
            sq, sq->id);

   /* Need to flush out buffered drawing commands so that they don't
    * get counted in the query results.
    */
   svga_hwtnl_flush_retry(svga);

   switch (sq->type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
   case PIPE_QUERY_OCCLUSION_PREDICATE:
   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
      if (svga_have_vgpu10(svga)) {
         ret = begin_query_vgpu10(svga, sq);
         /* also need to start the associated occlusion predicate query */
         if (sq->predicate) {
            enum pipe_error status;
            status = begin_query_vgpu10(svga, svga_query(sq->predicate));
            assert(status == PIPE_OK);
            (void) status;
         }
      } else {
         ret = begin_query_vgpu9(svga, sq);
      }
      assert(ret == PIPE_OK);
      (void) ret;
      break;
   case PIPE_QUERY_PRIMITIVES_GENERATED:
   case PIPE_QUERY_PRIMITIVES_EMITTED:
   case PIPE_QUERY_SO_STATISTICS:
   case PIPE_QUERY_TIMESTAMP:
      assert(svga_have_vgpu10(svga));
      ret = begin_query_vgpu10(svga, sq);
      assert(ret == PIPE_OK);
      break;
   case SVGA_QUERY_NUM_DRAW_CALLS:
      sq->begin_count = svga->hud.num_draw_calls;
      break;
   case SVGA_QUERY_NUM_FALLBACKS:
      sq->begin_count = svga->hud.num_fallbacks;
      break;
   case SVGA_QUERY_NUM_FLUSHES:
      sq->begin_count = svga->hud.num_flushes;
      break;
   case SVGA_QUERY_NUM_VALIDATIONS:
      sq->begin_count = svga->hud.num_validations;
      break;
   case SVGA_QUERY_MAP_BUFFER_TIME:
      sq->begin_count = svga->hud.map_buffer_time;
      break;
   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
      sq->begin_count = svga->hud.num_buffers_mapped;
      break;
   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
      sq->begin_count = svga->hud.num_textures_mapped;
      break;
   case SVGA_QUERY_NUM_BYTES_UPLOADED:
      sq->begin_count = svga->hud.num_bytes_uploaded;
      break;
   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
      sq->begin_count = svga->hud.command_buffer_size;
      break;
   case SVGA_QUERY_FLUSH_TIME:
      sq->begin_count = svga->hud.flush_time;
      break;
   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
      sq->begin_count = svga->hud.surface_write_flushes;
      break;
   case SVGA_QUERY_NUM_READBACKS:
      sq->begin_count = svga->hud.num_readbacks;
      break;
   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
      sq->begin_count = svga->hud.num_resource_updates;
      break;
   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
      sq->begin_count = svga->hud.num_buffer_uploads;
      break;
   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
      sq->begin_count = svga->hud.num_const_buf_updates;
      break;
   case SVGA_QUERY_NUM_CONST_UPDATES:
      sq->begin_count = svga->hud.num_const_updates;
      break;
   case SVGA_QUERY_MEMORY_USED:
   case SVGA_QUERY_NUM_SHADERS:
   case SVGA_QUERY_NUM_RESOURCES:
   case SVGA_QUERY_NUM_STATE_OBJECTS:
   case SVGA_QUERY_NUM_SURFACE_VIEWS:
   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
      /* nothing */
      break;
   default:
      assert(!"unexpected query type in svga_begin_query()");
   }

   svga->sq[sq->type] = sq;

   return true;
}


static bool
svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_query *sq = svga_query(q);
   enum pipe_error ret;

   assert(sq);
   assert(sq->type < SVGA_QUERY_MAX);

   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
            sq, sq->id);

   if (sq->type == PIPE_QUERY_TIMESTAMP && svga->sq[sq->type] != sq)
      svga_begin_query(pipe, q);

   svga_hwtnl_flush_retry(svga);

   assert(svga->sq[sq->type] == sq);

   switch (sq->type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
   case PIPE_QUERY_OCCLUSION_PREDICATE:
   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
      if (svga_have_vgpu10(svga)) {
         ret = end_query_vgpu10(svga, sq);
         /* also need to end the associated occlusion predicate query */
         if (sq->predicate) {
            enum pipe_error status;
            status = end_query_vgpu10(svga, svga_query(sq->predicate));
            assert(status == PIPE_OK);
            (void) status;
         }
      } else {
         ret = end_query_vgpu9(svga, sq);
      }
      assert(ret == PIPE_OK);
      (void) ret;
      break;
   case PIPE_QUERY_PRIMITIVES_GENERATED:
   case PIPE_QUERY_PRIMITIVES_EMITTED:
   case PIPE_QUERY_SO_STATISTICS:
   case PIPE_QUERY_TIMESTAMP:
      assert(svga_have_vgpu10(svga));
      ret = end_query_vgpu10(svga, sq);
      assert(ret == PIPE_OK);
      break;
   case SVGA_QUERY_NUM_DRAW_CALLS:
      sq->end_count = svga->hud.num_draw_calls;
      break;
   case SVGA_QUERY_NUM_FALLBACKS:
      sq->end_count = svga->hud.num_fallbacks;
      break;
   case SVGA_QUERY_NUM_FLUSHES:
      sq->end_count = svga->hud.num_flushes;
      break;
   case SVGA_QUERY_NUM_VALIDATIONS:
      sq->end_count = svga->hud.num_validations;
      break;
   case SVGA_QUERY_MAP_BUFFER_TIME:
      sq->end_count = svga->hud.map_buffer_time;
      break;
   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
      sq->end_count = svga->hud.num_buffers_mapped;
      break;
   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
      sq->end_count = svga->hud.num_textures_mapped;
      break;
   case SVGA_QUERY_NUM_BYTES_UPLOADED:
      sq->end_count = svga->hud.num_bytes_uploaded;
      break;
   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
      sq->end_count = svga->hud.command_buffer_size;
      break;
   case SVGA_QUERY_FLUSH_TIME:
      sq->end_count = svga->hud.flush_time;
      break;
   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
      sq->end_count = svga->hud.surface_write_flushes;
      break;
   case SVGA_QUERY_NUM_READBACKS:
      sq->end_count = svga->hud.num_readbacks;
      break;
   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
      sq->end_count = svga->hud.num_resource_updates;
      break;
   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
      sq->end_count = svga->hud.num_buffer_uploads;
      break;
   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
      sq->end_count = svga->hud.num_const_buf_updates;
      break;
   case SVGA_QUERY_NUM_CONST_UPDATES:
      sq->end_count = svga->hud.num_const_updates;
      break;
   case SVGA_QUERY_MEMORY_USED:
   case SVGA_QUERY_NUM_SHADERS:
   case SVGA_QUERY_NUM_RESOURCES:
   case SVGA_QUERY_NUM_STATE_OBJECTS:
   case SVGA_QUERY_NUM_SURFACE_VIEWS:
   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
      /* nothing */
      break;
   default:
      assert(!"unexpected query type in svga_end_query()");
   }
   svga->sq[sq->type] = NULL;
   return true;
}


static boolean
svga_get_query_result(struct pipe_context *pipe,
                      struct pipe_query *q,
                      boolean wait,
                      union pipe_query_result *vresult)
{
   struct svga_screen *svgascreen = svga_screen(pipe->screen);
   struct svga_context *svga = svga_context(pipe);
   struct svga_query *sq = svga_query(q);
   uint64_t *result = (uint64_t *)vresult;
   boolean ret = TRUE;

   assert(sq);

   SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d wait: %d\n",
            __FUNCTION__, sq, sq->id, wait);

   switch (sq->type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
      if (svga_have_vgpu10(svga)) {
         SVGADXOcclusionQueryResult occResult;
         ret = get_query_result_vgpu10(svga, sq, wait,
                                       (void *)&occResult, sizeof(occResult));
         *result = (uint64_t)occResult.samplesRendered;
      } else {
         ret = get_query_result_vgpu9(svga, sq, wait, result);
      }
      break;
   case PIPE_QUERY_OCCLUSION_PREDICATE:
   case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: {
      if (svga_have_vgpu10(svga)) {
         SVGADXOcclusionPredicateQueryResult occResult;
         ret = get_query_result_vgpu10(svga, sq, wait,
                                       (void *)&occResult, sizeof(occResult));
         vresult->b = occResult.anySamplesRendered != 0;
      } else {
         uint64_t count = 0;
         ret = get_query_result_vgpu9(svga, sq, wait, &count);
         vresult->b = count != 0;
      }
      break;
   }
   case PIPE_QUERY_SO_STATISTICS: {
      SVGADXStreamOutStatisticsQueryResult sResult;
      struct pipe_query_data_so_statistics *pResult =
         (struct pipe_query_data_so_statistics *)vresult;

      assert(svga_have_vgpu10(svga));
      ret = get_query_result_vgpu10(svga, sq, wait,
                                    (void *)&sResult, sizeof(sResult));
      pResult->num_primitives_written = sResult.numPrimitivesWritten;
      pResult->primitives_storage_needed = sResult.numPrimitivesRequired;
      break;
   }
   case PIPE_QUERY_TIMESTAMP: {
      SVGADXTimestampQueryResult sResult;

      assert(svga_have_vgpu10(svga));
      ret = get_query_result_vgpu10(svga, sq, wait,
                                    (void *)&sResult, sizeof(sResult));
      *result = (uint64_t)sResult.timestamp;
      break;
   }
   case PIPE_QUERY_PRIMITIVES_GENERATED: {
      SVGADXStreamOutStatisticsQueryResult sResult;

      assert(svga_have_vgpu10(svga));
      ret = get_query_result_vgpu10(svga, sq, wait,
                                    (void *)&sResult, sizeof sResult);
      *result = (uint64_t)sResult.numPrimitivesRequired;
      break;
   }
   case PIPE_QUERY_PRIMITIVES_EMITTED: {
      SVGADXStreamOutStatisticsQueryResult sResult;

      assert(svga_have_vgpu10(svga));
      ret = get_query_result_vgpu10(svga, sq, wait,
                                    (void *)&sResult, sizeof sResult);
      *result = (uint64_t)sResult.numPrimitivesWritten;
      break;
   }
   /* These are per-frame counters */
   case SVGA_QUERY_NUM_DRAW_CALLS:
   case SVGA_QUERY_NUM_FALLBACKS:
   case SVGA_QUERY_NUM_FLUSHES:
   case SVGA_QUERY_NUM_VALIDATIONS:
   case SVGA_QUERY_MAP_BUFFER_TIME:
   case SVGA_QUERY_NUM_BUFFERS_MAPPED:
   case SVGA_QUERY_NUM_TEXTURES_MAPPED:
   case SVGA_QUERY_NUM_BYTES_UPLOADED:
   case SVGA_QUERY_COMMAND_BUFFER_SIZE:
   case SVGA_QUERY_FLUSH_TIME:
   case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
   case SVGA_QUERY_NUM_READBACKS:
   case SVGA_QUERY_NUM_RESOURCE_UPDATES:
   case SVGA_QUERY_NUM_BUFFER_UPLOADS:
   case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
   case SVGA_QUERY_NUM_CONST_UPDATES:
      vresult->u64 = sq->end_count - sq->begin_count;
      break;
   /* These are running total counters */
   case SVGA_QUERY_MEMORY_USED:
      vresult->u64 = svgascreen->hud.total_resource_bytes;
      break;
   case SVGA_QUERY_NUM_SHADERS:
      vresult->u64 = svga->hud.num_shaders;
      break;
   case SVGA_QUERY_NUM_RESOURCES:
      vresult->u64 = svgascreen->hud.num_resources;
      break;
   case SVGA_QUERY_NUM_STATE_OBJECTS:
      vresult->u64 = (svga->hud.num_blend_objects +
                      svga->hud.num_depthstencil_objects +
                      svga->hud.num_rasterizer_objects +
                      svga->hud.num_sampler_objects +
                      svga->hud.num_samplerview_objects +
                      svga->hud.num_vertexelement_objects);
      break;
   case SVGA_QUERY_NUM_SURFACE_VIEWS:
      vresult->u64 = svga->hud.num_surface_views;
      break;
   case SVGA_QUERY_NUM_GENERATE_MIPMAP:
      vresult->u64 = svga->hud.num_generate_mipmap;
      break;
   case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
      vresult->u64 = svgascreen->hud.num_failed_allocations;
      break;
   default:
      assert(!"unexpected query type in svga_get_query_result");
   }

   SVGA_DBG(DEBUG_QUERY, "%s result %d\n", __FUNCTION__, *((uint64_t *)vresult));

   return ret;
}

static void
svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
                      boolean condition, enum pipe_render_cond_flag mode)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   struct svga_query *sq = svga_query(q);
   SVGA3dQueryId queryId;
   enum pipe_error ret;

   SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);

   assert(svga_have_vgpu10(svga));
   if (sq == NULL) {
      queryId = SVGA3D_INVALID_ID;
   }
   else {
      assert(sq->svga_type == SVGA3D_QUERYTYPE_OCCLUSION ||
             sq->svga_type == SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE);

      if (sq->svga_type == SVGA3D_QUERYTYPE_OCCLUSION) {
         assert(sq->predicate);
         /**
          * For conditional rendering, make sure to use the associated
          * predicate query.
          */
         sq = svga_query(sq->predicate);
      }
      queryId = sq->id;

      if ((mode == PIPE_RENDER_COND_WAIT ||
           mode == PIPE_RENDER_COND_BY_REGION_WAIT) && sq->fence) {
         sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
                           SVGA_FENCE_FLAG_QUERY);
      }
   }
   /*
    * if the kernel module doesn't support the predication command,
    * we'll just render unconditionally.
    * This is probably acceptable for the typical case of occlusion culling.
    */
   if (sws->have_set_predication_cmd) {
      ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
                                         (uint32) condition);
      if (ret != PIPE_OK) {
         svga_context_flush(svga, NULL);
         ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
                                            (uint32) condition);
      }
      svga->pred.query_id = queryId;
      svga->pred.cond = condition;
   }

   svga->render_condition = (sq != NULL);
}


/*
 * This function is a workaround because we lack the ability to query
 * renderer's time synchornously.
 */
static uint64_t
svga_get_timestamp(struct pipe_context *pipe)
{
   struct pipe_query *q = svga_create_query(pipe, PIPE_QUERY_TIMESTAMP, 0);
   union pipe_query_result result;

   svga_begin_query(pipe, q);
   svga_end_query(pipe,q);
   svga_get_query_result(pipe, q, TRUE, &result);
   svga_destroy_query(pipe, q);

   return result.u64;
}


static void
svga_set_active_query_state(struct pipe_context *pipe, boolean enable)
{
}


/**
 * \brief Toggle conditional rendering if already enabled
 *
 * \param svga[in]  The svga context
 * \param render_condition_enabled[in]  Whether to ignore requests to turn
 * conditional rendering off
 * \param on[in]  Whether to turn conditional rendering on or off
 */
void
svga_toggle_render_condition(struct svga_context *svga,
                             boolean render_condition_enabled,
                             boolean on)
{
   SVGA3dQueryId query_id;
   enum pipe_error ret;

   if (render_condition_enabled ||
       svga->pred.query_id == SVGA3D_INVALID_ID) {
      return;
   }

   /*
    * If we get here, it means that the system supports
    * conditional rendering since svga->pred.query_id has already been
    * modified for this context and thus support has already been
    * verified.
    */
   query_id = on ? svga->pred.query_id : SVGA3D_INVALID_ID;

   ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
                                      (uint32) svga->pred.cond);
   if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
                                         (uint32) svga->pred.cond);
      assert(ret == PIPE_OK);
   }
}


void
svga_init_query_functions(struct svga_context *svga)
{
   svga->pipe.create_query = svga_create_query;
   svga->pipe.destroy_query = svga_destroy_query;
   svga->pipe.begin_query = svga_begin_query;
   svga->pipe.end_query = svga_end_query;
   svga->pipe.get_query_result = svga_get_query_result;
   svga->pipe.set_active_query_state = svga_set_active_query_state;
   svga->pipe.render_condition = svga_render_condition;
   svga->pipe.get_timestamp = svga_get_timestamp;
}
