Home | History | Annotate | Download | only in svga
      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  */
     43 struct pipe_query {
     44    int dummy;
     45 };
     46 
     47 struct 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 */
     74 static inline struct svga_query *
     75 svga_query(struct pipe_query *q)
     76 {
     77    return (struct svga_query *)q;
     78 }
     79 
     80 /**
     81  * VGPU9
     82  */
     83 
     84 static boolean
     85 svga_get_query_result(struct pipe_context *pipe,
     86                       struct pipe_query *q,
     87                       boolean wait,
     88                       union pipe_query_result *result);
     89 
     90 static enum pipe_error
     91 define_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 
    121 static enum pipe_error
    122 begin_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 
    151 static enum pipe_error
    152 end_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 
    167 static boolean
    168 get_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, PIPE_TIMEOUT_INFINITE,
    195                         SVGA_FENCE_FLAG_QUERY);
    196       state = sq->queryResult->state;
    197    }
    198 
    199    assert(state == SVGA3D_QUERYSTATE_SUCCEEDED ||
    200           state == SVGA3D_QUERYSTATE_FAILED);
    201 
    202    *result = (uint64_t)sq->queryResult->result32;
    203    return TRUE;
    204 }
    205 
    206 
    207 /**
    208  * VGPU10
    209  *
    210  * There is one query mob allocated for each context to be shared by all
    211  * query types. The mob is used to hold queries's state and result. Since
    212  * each query result type is of different length, to ease the query allocation
    213  * management, the mob is divided into memory blocks. Each memory block
    214  * will hold queries of the same type. Multiple memory blocks can be allocated
    215  * for a particular query type.
    216  *
    217  * Currently each memory block is of 184 bytes. We support up to 128
    218  * memory blocks. The query memory size is arbitrary right now.
    219  * Each occlusion query takes about 8 bytes. One memory block can accomodate
    220  * 23 occlusion queries. 128 of those blocks can support up to 2944 occlusion
    221  * queries. That seems reasonable for now. If we think this limit is
    222  * not enough, we can increase the limit or try to grow the mob in runtime.
    223  * Note, SVGA device does not impose one mob per context for queries,
    224  * we could allocate multiple mobs for queries; however, wddm KMD does not
    225  * currently support that.
    226  *
    227  * Also note that the GL guest driver does not issue any of the
    228  * following commands: DXMoveQuery, DXBindAllQuery & DXReadbackAllQuery.
    229  */
    230 #define SVGA_QUERY_MEM_BLOCK_SIZE    (sizeof(SVGADXQueryResultUnion) * 2)
    231 #define SVGA_QUERY_MEM_SIZE          (128 * SVGA_QUERY_MEM_BLOCK_SIZE)
    232 
    233 struct svga_qmem_alloc_entry
    234 {
    235    unsigned start_offset;               /* start offset of the memory block */
    236    unsigned block_index;                /* block index of the memory block */
    237    unsigned query_size;                 /* query size in this memory block */
    238    unsigned nquery;                     /* number of queries allocated */
    239    struct util_bitmask *alloc_mask;     /* allocation mask */
    240    struct svga_qmem_alloc_entry *next;  /* next memory block */
    241 };
    242 
    243 
    244 /**
    245  * Allocate a memory block from the query object memory
    246  * \return -1 if out of memory, else index of the query memory block
    247  */
    248 static int
    249 allocate_query_block(struct svga_context *svga)
    250 {
    251    int index;
    252    unsigned offset;
    253 
    254    /* Find the next available query block */
    255    index = util_bitmask_add(svga->gb_query_alloc_mask);
    256 
    257    if (index == UTIL_BITMASK_INVALID_INDEX)
    258       return -1;
    259 
    260    offset = index * SVGA_QUERY_MEM_BLOCK_SIZE;
    261    if (offset >= svga->gb_query_len) {
    262       unsigned i;
    263 
    264       /**
    265        * All the memory blocks are allocated, lets see if there is
    266        * any empty memory block around that can be freed up.
    267        */
    268       index = -1;
    269       for (i = 0; i < SVGA3D_QUERYTYPE_MAX && index == -1; i++) {
    270          struct svga_qmem_alloc_entry *alloc_entry;
    271          struct svga_qmem_alloc_entry *prev_alloc_entry = NULL;
    272 
    273          alloc_entry = svga->gb_query_map[i];
    274          while (alloc_entry && index == -1) {
    275             if (alloc_entry->nquery == 0) {
    276                /* This memory block is empty, it can be recycled. */
    277                if (prev_alloc_entry) {
    278                   prev_alloc_entry->next = alloc_entry->next;
    279                } else {
    280                   svga->gb_query_map[i] = alloc_entry->next;
    281                }
    282                index = alloc_entry->block_index;
    283             } else {
    284                prev_alloc_entry = alloc_entry;
    285                alloc_entry = alloc_entry->next;
    286             }
    287          }
    288       }
    289    }
    290 
    291    return index;
    292 }
    293 
    294 /**
    295  * Allocate a slot in the specified memory block.
    296  * All slots in this memory block are of the same size.
    297  *
    298  * \return -1 if out of memory, else index of the query slot
    299  */
    300 static int
    301 allocate_query_slot(struct svga_context *svga,
    302                     struct svga_qmem_alloc_entry *alloc)
    303 {
    304    int index;
    305    unsigned offset;
    306 
    307    /* Find the next available slot */
    308    index = util_bitmask_add(alloc->alloc_mask);
    309 
    310    if (index == UTIL_BITMASK_INVALID_INDEX)
    311       return -1;
    312 
    313    offset = index * alloc->query_size;
    314    if (offset >= SVGA_QUERY_MEM_BLOCK_SIZE)
    315       return -1;
    316 
    317    alloc->nquery++;
    318 
    319    return index;
    320 }
    321 
    322 /**
    323  * Deallocate the specified slot in the memory block.
    324  * If all slots are freed up, then deallocate the memory block
    325  * as well, so it can be allocated for other query type
    326  */
    327 static void
    328 deallocate_query_slot(struct svga_context *svga,
    329                       struct svga_qmem_alloc_entry *alloc,
    330                       unsigned index)
    331 {
    332    assert(index != UTIL_BITMASK_INVALID_INDEX);
    333 
    334    util_bitmask_clear(alloc->alloc_mask, index);
    335    alloc->nquery--;
    336 
    337    /**
    338     * Don't worry about deallocating the empty memory block here.
    339     * The empty memory block will be recycled when no more memory block
    340     * can be allocated.
    341     */
    342 }
    343 
    344 static struct svga_qmem_alloc_entry *
    345 allocate_query_block_entry(struct svga_context *svga,
    346                            unsigned len)
    347 {
    348    struct svga_qmem_alloc_entry *alloc_entry;
    349    int block_index = -1;
    350 
    351    block_index = allocate_query_block(svga);
    352    if (block_index == -1)
    353       return NULL;
    354    alloc_entry = CALLOC_STRUCT(svga_qmem_alloc_entry);
    355    if (!alloc_entry)
    356       return NULL;
    357 
    358    alloc_entry->block_index = block_index;
    359    alloc_entry->start_offset = block_index * SVGA_QUERY_MEM_BLOCK_SIZE;
    360    alloc_entry->nquery = 0;
    361    alloc_entry->alloc_mask = util_bitmask_create();
    362    alloc_entry->next = NULL;
    363    alloc_entry->query_size = len;
    364 
    365    return alloc_entry;
    366 }
    367 
    368 /**
    369  * Allocate a memory slot for a query of the specified type.
    370  * It will first search through the memory blocks that are allocated
    371  * for the query type. If no memory slot is available, it will try
    372  * to allocate another memory block within the query object memory for
    373  * this query type.
    374  */
    375 static int
    376 allocate_query(struct svga_context *svga,
    377                SVGA3dQueryType type,
    378                unsigned len)
    379 {
    380    struct svga_qmem_alloc_entry *alloc_entry;
    381    int slot_index = -1;
    382    unsigned offset;
    383 
    384    assert(type < SVGA3D_QUERYTYPE_MAX);
    385 
    386    alloc_entry = svga->gb_query_map[type];
    387 
    388    if (!alloc_entry) {
    389       /**
    390        * No query memory block has been allocated for this query type,
    391        * allocate one now
    392        */
    393       alloc_entry = allocate_query_block_entry(svga, len);
    394       if (!alloc_entry)
    395          return -1;
    396       svga->gb_query_map[type] = alloc_entry;
    397    }
    398 
    399    /* Allocate a slot within the memory block allocated for this query type */
    400    slot_index = allocate_query_slot(svga, alloc_entry);
    401 
    402    if (slot_index == -1) {
    403       /* This query memory block is full, allocate another one */
    404       alloc_entry = allocate_query_block_entry(svga, len);
    405       if (!alloc_entry)
    406          return -1;
    407       alloc_entry->next = svga->gb_query_map[type];
    408       svga->gb_query_map[type] = alloc_entry;
    409       slot_index = allocate_query_slot(svga, alloc_entry);
    410    }
    411 
    412    assert(slot_index != -1);
    413    offset = slot_index * len + alloc_entry->start_offset;
    414 
    415    return offset;
    416 }
    417 
    418 
    419 /**
    420  * Deallocate memory slot allocated for the specified query
    421  */
    422 static void
    423 deallocate_query(struct svga_context *svga,
    424                  struct svga_query *sq)
    425 {
    426    struct svga_qmem_alloc_entry *alloc_entry;
    427    unsigned slot_index;
    428    unsigned offset = sq->offset;
    429 
    430    alloc_entry = svga->gb_query_map[sq->svga_type];
    431 
    432    while (alloc_entry) {
    433       if (offset >= alloc_entry->start_offset &&
    434           offset < alloc_entry->start_offset + SVGA_QUERY_MEM_BLOCK_SIZE) {
    435 
    436          /* The slot belongs to this memory block, deallocate it */
    437          slot_index = (offset - alloc_entry->start_offset) /
    438                       alloc_entry->query_size;
    439          deallocate_query_slot(svga, alloc_entry, slot_index);
    440          alloc_entry = NULL;
    441       } else {
    442          alloc_entry = alloc_entry->next;
    443       }
    444    }
    445 }
    446 
    447 
    448 /**
    449  * Destroy the gb query object and all the related query structures
    450  */
    451 static void
    452 destroy_gb_query_obj(struct svga_context *svga)
    453 {
    454    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    455    unsigned i;
    456 
    457    for (i = 0; i < SVGA3D_QUERYTYPE_MAX; i++) {
    458       struct svga_qmem_alloc_entry *alloc_entry, *next;
    459       alloc_entry = svga->gb_query_map[i];
    460       while (alloc_entry) {
    461          next = alloc_entry->next;
    462          util_bitmask_destroy(alloc_entry->alloc_mask);
    463          FREE(alloc_entry);
    464          alloc_entry = next;
    465       }
    466       svga->gb_query_map[i] = NULL;
    467    }
    468 
    469    if (svga->gb_query)
    470       sws->query_destroy(sws, svga->gb_query);
    471    svga->gb_query = NULL;
    472 
    473    util_bitmask_destroy(svga->gb_query_alloc_mask);
    474 }
    475 
    476 /**
    477  * Define query and create the gb query object if it is not already created.
    478  * There is only one gb query object per context which will be shared by
    479  * queries of all types.
    480  */
    481 static enum pipe_error
    482 define_query_vgpu10(struct svga_context *svga,
    483                     struct svga_query *sq, int resultLen)
    484 {
    485    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    486    int qlen;
    487    enum pipe_error ret = PIPE_OK;
    488 
    489    SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
    490 
    491    if (svga->gb_query == NULL) {
    492       /* Create a gb query object */
    493       svga->gb_query = sws->query_create(sws, SVGA_QUERY_MEM_SIZE);
    494       if (!svga->gb_query)
    495          return PIPE_ERROR_OUT_OF_MEMORY;
    496       svga->gb_query_len = SVGA_QUERY_MEM_SIZE;
    497       memset (svga->gb_query_map, 0, sizeof(svga->gb_query_map));
    498       svga->gb_query_alloc_mask = util_bitmask_create();
    499 
    500       /* Bind the query object to the context */
    501       if (svga->swc->query_bind(svga->swc, svga->gb_query,
    502                                 SVGA_QUERY_FLAG_SET) != PIPE_OK) {
    503          svga_context_flush(svga, NULL);
    504          svga->swc->query_bind(svga->swc, svga->gb_query,
    505                                SVGA_QUERY_FLAG_SET);
    506       }
    507    }
    508 
    509    sq->gb_query = svga->gb_query;
    510 
    511    /* Allocate an integer ID for this query */
    512    sq->id = util_bitmask_add(svga->query_id_bm);
    513    if (sq->id == UTIL_BITMASK_INVALID_INDEX)
    514       return PIPE_ERROR_OUT_OF_MEMORY;
    515 
    516    /* Find a slot for this query in the gb object */
    517    qlen = resultLen + sizeof(SVGA3dQueryState);
    518    sq->offset = allocate_query(svga, sq->svga_type, qlen);
    519    if (sq->offset == -1)
    520       return PIPE_ERROR_OUT_OF_MEMORY;
    521 
    522    SVGA_DBG(DEBUG_QUERY, "   query type=%d qid=0x%x offset=%d\n",
    523             sq->svga_type, sq->id, sq->offset);
    524 
    525    /**
    526     * Send SVGA3D commands to define the query
    527     */
    528    ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
    529    if (ret != PIPE_OK) {
    530       svga_context_flush(svga, NULL);
    531       ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
    532    }
    533    if (ret != PIPE_OK)
    534       return PIPE_ERROR_OUT_OF_MEMORY;
    535 
    536    ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
    537    if (ret != PIPE_OK) {
    538       svga_context_flush(svga, NULL);
    539       ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
    540    }
    541    assert(ret == PIPE_OK);
    542 
    543    ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
    544    if (ret != PIPE_OK) {
    545       svga_context_flush(svga, NULL);
    546       ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
    547    }
    548    assert(ret == PIPE_OK);
    549 
    550    return PIPE_OK;
    551 }
    552 
    553 static enum pipe_error
    554 destroy_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
    555 {
    556    enum pipe_error ret;
    557 
    558    ret = SVGA3D_vgpu10_DestroyQuery(svga->swc, sq->id);
    559 
    560    /* Deallocate the memory slot allocated for this query */
    561    deallocate_query(svga, sq);
    562 
    563    return ret;
    564 }
    565 
    566 
    567 /**
    568  * Rebind queryies to the context.
    569  */
    570 static void
    571 rebind_vgpu10_query(struct svga_context *svga)
    572 {
    573    if (svga->swc->query_bind(svga->swc, svga->gb_query,
    574                              SVGA_QUERY_FLAG_REF) != PIPE_OK) {
    575       svga_context_flush(svga, NULL);
    576       svga->swc->query_bind(svga->swc, svga->gb_query,
    577                             SVGA_QUERY_FLAG_REF);
    578    }
    579 
    580    svga->rebind.flags.query = FALSE;
    581 }
    582 
    583 
    584 static enum pipe_error
    585 begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
    586 {
    587    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    588    enum pipe_error ret = PIPE_OK;
    589    int status = 0;
    590 
    591    sws->fence_reference(sws, &sq->fence, NULL);
    592 
    593    /* Initialize the query state to NEW */
    594    status = sws->query_init(sws, sq->gb_query, sq->offset, SVGA3D_QUERYSTATE_NEW);
    595    if (status)
    596       return PIPE_ERROR;
    597 
    598    if (svga->rebind.flags.query) {
    599       rebind_vgpu10_query(svga);
    600    }
    601 
    602    /* Send the BeginQuery command to the device */
    603    ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
    604    if (ret != PIPE_OK) {
    605       svga_context_flush(svga, NULL);
    606       ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
    607    }
    608    return ret;
    609 }
    610 
    611 static enum pipe_error
    612 end_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
    613 {
    614    enum pipe_error ret = PIPE_OK;
    615 
    616    if (svga->rebind.flags.query) {
    617       rebind_vgpu10_query(svga);
    618    }
    619 
    620    ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
    621    if (ret != PIPE_OK) {
    622       svga_context_flush(svga, NULL);
    623       ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
    624    }
    625 
    626    return ret;
    627 }
    628 
    629 static boolean
    630 get_query_result_vgpu10(struct svga_context *svga, struct svga_query *sq,
    631                         boolean wait, void *result, int resultLen)
    632 {
    633    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    634    SVGA3dQueryState queryState;
    635 
    636    if (svga->rebind.flags.query) {
    637       rebind_vgpu10_query(svga);
    638    }
    639 
    640    sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);
    641 
    642    if (queryState != SVGA3D_QUERYSTATE_SUCCEEDED && !sq->fence) {
    643       /* We don't have the query result yet, and the query hasn't been
    644        * submitted.  We need to submit it now since the GL spec says
    645        * "Querying the state for a given occlusion query forces that
    646        * occlusion query to complete within a finite amount of time."
    647        */
    648       svga_context_flush(svga, &sq->fence);
    649    }
    650 
    651    if (queryState == SVGA3D_QUERYSTATE_PENDING ||
    652        queryState == SVGA3D_QUERYSTATE_NEW) {
    653       if (!wait)
    654          return FALSE;
    655       sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
    656                         SVGA_FENCE_FLAG_QUERY);
    657       sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);
    658    }
    659 
    660    assert(queryState == SVGA3D_QUERYSTATE_SUCCEEDED ||
    661           queryState == SVGA3D_QUERYSTATE_FAILED);
    662 
    663    return TRUE;
    664 }
    665 
    666 static struct pipe_query *
    667 svga_create_query(struct pipe_context *pipe,
    668                   unsigned query_type,
    669                   unsigned index)
    670 {
    671    struct svga_context *svga = svga_context(pipe);
    672    struct svga_query *sq;
    673 
    674    assert(query_type < SVGA_QUERY_MAX);
    675 
    676    sq = CALLOC_STRUCT(svga_query);
    677    if (!sq)
    678       goto fail;
    679 
    680    /* Allocate an integer ID for the query */
    681    sq->id = util_bitmask_add(svga->query_id_bm);
    682    if (sq->id == UTIL_BITMASK_INVALID_INDEX)
    683       goto fail;
    684 
    685    SVGA_DBG(DEBUG_QUERY, "%s type=%d sq=0x%x id=%d\n", __FUNCTION__,
    686             query_type, sq, sq->id);
    687 
    688    switch (query_type) {
    689    case PIPE_QUERY_OCCLUSION_COUNTER:
    690       sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION;
    691       if (svga_have_vgpu10(svga)) {
    692          define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionQueryResult));
    693 
    694          /**
    695           * In OpenGL, occlusion counter query can be used in conditional
    696           * rendering; however, in DX10, only OCCLUSION_PREDICATE query can
    697           * be used for predication. Hence, we need to create an occlusion
    698           * predicate query along with the occlusion counter query. So when
    699           * the occlusion counter query is used for predication, the associated
    700           * query of occlusion predicate type will be used
    701           * in the SetPredication command.
    702           */
    703          sq->predicate = svga_create_query(pipe, PIPE_QUERY_OCCLUSION_PREDICATE, index);
    704 
    705       } else {
    706          define_query_vgpu9(svga, sq);
    707       }
    708       break;
    709    case PIPE_QUERY_OCCLUSION_PREDICATE:
    710    case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
    711       if (svga_have_vgpu10(svga)) {
    712          sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE;
    713          define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionPredicateQueryResult));
    714       } else {
    715          sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION;
    716          define_query_vgpu9(svga, sq);
    717       }
    718       break;
    719    case PIPE_QUERY_PRIMITIVES_GENERATED:
    720    case PIPE_QUERY_PRIMITIVES_EMITTED:
    721    case PIPE_QUERY_SO_STATISTICS:
    722       assert(svga_have_vgpu10(svga));
    723       sq->svga_type = SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS;
    724       define_query_vgpu10(svga, sq,
    725                           sizeof(SVGADXStreamOutStatisticsQueryResult));
    726       break;
    727    case PIPE_QUERY_TIMESTAMP:
    728       assert(svga_have_vgpu10(svga));
    729       sq->svga_type = SVGA3D_QUERYTYPE_TIMESTAMP;
    730       define_query_vgpu10(svga, sq,
    731                           sizeof(SVGADXTimestampQueryResult));
    732       break;
    733    case SVGA_QUERY_NUM_DRAW_CALLS:
    734    case SVGA_QUERY_NUM_FALLBACKS:
    735    case SVGA_QUERY_NUM_FLUSHES:
    736    case SVGA_QUERY_NUM_VALIDATIONS:
    737    case SVGA_QUERY_NUM_BUFFERS_MAPPED:
    738    case SVGA_QUERY_NUM_TEXTURES_MAPPED:
    739    case SVGA_QUERY_NUM_BYTES_UPLOADED:
    740    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
    741    case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
    742    case SVGA_QUERY_MEMORY_USED:
    743    case SVGA_QUERY_NUM_SHADERS:
    744    case SVGA_QUERY_NUM_RESOURCES:
    745    case SVGA_QUERY_NUM_STATE_OBJECTS:
    746    case SVGA_QUERY_NUM_SURFACE_VIEWS:
    747    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
    748    case SVGA_QUERY_NUM_READBACKS:
    749    case SVGA_QUERY_NUM_RESOURCE_UPDATES:
    750    case SVGA_QUERY_NUM_BUFFER_UPLOADS:
    751    case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
    752    case SVGA_QUERY_NUM_CONST_UPDATES:
    753    case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
    754    case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
    755       break;
    756    case SVGA_QUERY_FLUSH_TIME:
    757    case SVGA_QUERY_MAP_BUFFER_TIME:
    758       /* These queries need os_time_get() */
    759       svga->hud.uses_time = TRUE;
    760       break;
    761    default:
    762       assert(!"unexpected query type in svga_create_query()");
    763    }
    764 
    765    sq->type = query_type;
    766 
    767    return &sq->base;
    768 
    769 fail:
    770    FREE(sq);
    771    return NULL;
    772 }
    773 
    774 static void
    775 svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
    776 {
    777    struct svga_context *svga = svga_context(pipe);
    778    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
    779    struct svga_query *sq;
    780 
    781    if (!q) {
    782       destroy_gb_query_obj(svga);
    783       return;
    784    }
    785 
    786    sq = svga_query(q);
    787 
    788    SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
    789             sq, sq->id);
    790 
    791    switch (sq->type) {
    792    case PIPE_QUERY_OCCLUSION_COUNTER:
    793    case PIPE_QUERY_OCCLUSION_PREDICATE:
    794    case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
    795       if (svga_have_vgpu10(svga)) {
    796          /* make sure to also destroy any associated predicate query */
    797          if (sq->predicate)
    798             svga_destroy_query(pipe, sq->predicate);
    799          destroy_query_vgpu10(svga, sq);
    800       } else {
    801          sws->buffer_destroy(sws, sq->hwbuf);
    802       }
    803       sws->fence_reference(sws, &sq->fence, NULL);
    804       break;
    805    case PIPE_QUERY_PRIMITIVES_GENERATED:
    806    case PIPE_QUERY_PRIMITIVES_EMITTED:
    807    case PIPE_QUERY_SO_STATISTICS:
    808    case PIPE_QUERY_TIMESTAMP:
    809       assert(svga_have_vgpu10(svga));
    810       destroy_query_vgpu10(svga, sq);
    811       sws->fence_reference(sws, &sq->fence, NULL);
    812       break;
    813    case SVGA_QUERY_NUM_DRAW_CALLS:
    814    case SVGA_QUERY_NUM_FALLBACKS:
    815    case SVGA_QUERY_NUM_FLUSHES:
    816    case SVGA_QUERY_NUM_VALIDATIONS:
    817    case SVGA_QUERY_MAP_BUFFER_TIME:
    818    case SVGA_QUERY_NUM_BUFFERS_MAPPED:
    819    case SVGA_QUERY_NUM_TEXTURES_MAPPED:
    820    case SVGA_QUERY_NUM_BYTES_UPLOADED:
    821    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
    822    case SVGA_QUERY_FLUSH_TIME:
    823    case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
    824    case SVGA_QUERY_MEMORY_USED:
    825    case SVGA_QUERY_NUM_SHADERS:
    826    case SVGA_QUERY_NUM_RESOURCES:
    827    case SVGA_QUERY_NUM_STATE_OBJECTS:
    828    case SVGA_QUERY_NUM_SURFACE_VIEWS:
    829    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
    830    case SVGA_QUERY_NUM_READBACKS:
    831    case SVGA_QUERY_NUM_RESOURCE_UPDATES:
    832    case SVGA_QUERY_NUM_BUFFER_UPLOADS:
    833    case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
    834    case SVGA_QUERY_NUM_CONST_UPDATES:
    835    case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
    836    case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
    837       /* nothing */
    838       break;
    839    default:
    840       assert(!"svga: unexpected query type in svga_destroy_query()");
    841    }
    842 
    843    /* Free the query id */
    844    util_bitmask_clear(svga->query_id_bm, sq->id);
    845 
    846    FREE(sq);
    847 }
    848 
    849 
    850 static boolean
    851 svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    852 {
    853    struct svga_context *svga = svga_context(pipe);
    854    struct svga_query *sq = svga_query(q);
    855    enum pipe_error ret;
    856 
    857    assert(sq);
    858    assert(sq->type < SVGA_QUERY_MAX);
    859 
    860    SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
    861             sq, sq->id);
    862 
    863    /* Need to flush out buffered drawing commands so that they don't
    864     * get counted in the query results.
    865     */
    866    svga_hwtnl_flush_retry(svga);
    867 
    868    switch (sq->type) {
    869    case PIPE_QUERY_OCCLUSION_COUNTER:
    870    case PIPE_QUERY_OCCLUSION_PREDICATE:
    871    case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
    872       if (svga_have_vgpu10(svga)) {
    873          ret = begin_query_vgpu10(svga, sq);
    874          /* also need to start the associated occlusion predicate query */
    875          if (sq->predicate) {
    876             enum pipe_error status;
    877             status = begin_query_vgpu10(svga, svga_query(sq->predicate));
    878             assert(status == PIPE_OK);
    879             (void) status;
    880          }
    881       } else {
    882          ret = begin_query_vgpu9(svga, sq);
    883       }
    884       assert(ret == PIPE_OK);
    885       (void) ret;
    886       break;
    887    case PIPE_QUERY_PRIMITIVES_GENERATED:
    888    case PIPE_QUERY_PRIMITIVES_EMITTED:
    889    case PIPE_QUERY_SO_STATISTICS:
    890    case PIPE_QUERY_TIMESTAMP:
    891       assert(svga_have_vgpu10(svga));
    892       ret = begin_query_vgpu10(svga, sq);
    893       assert(ret == PIPE_OK);
    894       break;
    895    case SVGA_QUERY_NUM_DRAW_CALLS:
    896       sq->begin_count = svga->hud.num_draw_calls;
    897       break;
    898    case SVGA_QUERY_NUM_FALLBACKS:
    899       sq->begin_count = svga->hud.num_fallbacks;
    900       break;
    901    case SVGA_QUERY_NUM_FLUSHES:
    902       sq->begin_count = svga->hud.num_flushes;
    903       break;
    904    case SVGA_QUERY_NUM_VALIDATIONS:
    905       sq->begin_count = svga->hud.num_validations;
    906       break;
    907    case SVGA_QUERY_MAP_BUFFER_TIME:
    908       sq->begin_count = svga->hud.map_buffer_time;
    909       break;
    910    case SVGA_QUERY_NUM_BUFFERS_MAPPED:
    911       sq->begin_count = svga->hud.num_buffers_mapped;
    912       break;
    913    case SVGA_QUERY_NUM_TEXTURES_MAPPED:
    914       sq->begin_count = svga->hud.num_textures_mapped;
    915       break;
    916    case SVGA_QUERY_NUM_BYTES_UPLOADED:
    917       sq->begin_count = svga->hud.num_bytes_uploaded;
    918       break;
    919    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
    920       sq->begin_count = svga->hud.command_buffer_size;
    921       break;
    922    case SVGA_QUERY_FLUSH_TIME:
    923       sq->begin_count = svga->hud.flush_time;
    924       break;
    925    case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
    926       sq->begin_count = svga->hud.surface_write_flushes;
    927       break;
    928    case SVGA_QUERY_NUM_READBACKS:
    929       sq->begin_count = svga->hud.num_readbacks;
    930       break;
    931    case SVGA_QUERY_NUM_RESOURCE_UPDATES:
    932       sq->begin_count = svga->hud.num_resource_updates;
    933       break;
    934    case SVGA_QUERY_NUM_BUFFER_UPLOADS:
    935       sq->begin_count = svga->hud.num_buffer_uploads;
    936       break;
    937    case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
    938       sq->begin_count = svga->hud.num_const_buf_updates;
    939       break;
    940    case SVGA_QUERY_NUM_CONST_UPDATES:
    941       sq->begin_count = svga->hud.num_const_updates;
    942       break;
    943    case SVGA_QUERY_MEMORY_USED:
    944    case SVGA_QUERY_NUM_SHADERS:
    945    case SVGA_QUERY_NUM_RESOURCES:
    946    case SVGA_QUERY_NUM_STATE_OBJECTS:
    947    case SVGA_QUERY_NUM_SURFACE_VIEWS:
    948    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
    949    case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
    950    case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
    951       /* nothing */
    952       break;
    953    default:
    954       assert(!"unexpected query type in svga_begin_query()");
    955    }
    956 
    957    svga->sq[sq->type] = sq;
    958 
    959    return true;
    960 }
    961 
    962 
    963 static bool
    964 svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
    965 {
    966    struct svga_context *svga = svga_context(pipe);
    967    struct svga_query *sq = svga_query(q);
    968    enum pipe_error ret;
    969 
    970    assert(sq);
    971    assert(sq->type < SVGA_QUERY_MAX);
    972 
    973    SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
    974             sq, sq->id);
    975 
    976    if (sq->type == PIPE_QUERY_TIMESTAMP && svga->sq[sq->type] != sq)
    977       svga_begin_query(pipe, q);
    978 
    979    svga_hwtnl_flush_retry(svga);
    980 
    981    assert(svga->sq[sq->type] == sq);
    982 
    983    switch (sq->type) {
    984    case PIPE_QUERY_OCCLUSION_COUNTER:
    985    case PIPE_QUERY_OCCLUSION_PREDICATE:
    986    case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
    987       if (svga_have_vgpu10(svga)) {
    988          ret = end_query_vgpu10(svga, sq);
    989          /* also need to end the associated occlusion predicate query */
    990          if (sq->predicate) {
    991             enum pipe_error status;
    992             status = end_query_vgpu10(svga, svga_query(sq->predicate));
    993             assert(status == PIPE_OK);
    994             (void) status;
    995          }
    996       } else {
    997          ret = end_query_vgpu9(svga, sq);
    998       }
    999       assert(ret == PIPE_OK);
   1000       (void) ret;
   1001       break;
   1002    case PIPE_QUERY_PRIMITIVES_GENERATED:
   1003    case PIPE_QUERY_PRIMITIVES_EMITTED:
   1004    case PIPE_QUERY_SO_STATISTICS:
   1005    case PIPE_QUERY_TIMESTAMP:
   1006       assert(svga_have_vgpu10(svga));
   1007       ret = end_query_vgpu10(svga, sq);
   1008       assert(ret == PIPE_OK);
   1009       break;
   1010    case SVGA_QUERY_NUM_DRAW_CALLS:
   1011       sq->end_count = svga->hud.num_draw_calls;
   1012       break;
   1013    case SVGA_QUERY_NUM_FALLBACKS:
   1014       sq->end_count = svga->hud.num_fallbacks;
   1015       break;
   1016    case SVGA_QUERY_NUM_FLUSHES:
   1017       sq->end_count = svga->hud.num_flushes;
   1018       break;
   1019    case SVGA_QUERY_NUM_VALIDATIONS:
   1020       sq->end_count = svga->hud.num_validations;
   1021       break;
   1022    case SVGA_QUERY_MAP_BUFFER_TIME:
   1023       sq->end_count = svga->hud.map_buffer_time;
   1024       break;
   1025    case SVGA_QUERY_NUM_BUFFERS_MAPPED:
   1026       sq->end_count = svga->hud.num_buffers_mapped;
   1027       break;
   1028    case SVGA_QUERY_NUM_TEXTURES_MAPPED:
   1029       sq->end_count = svga->hud.num_textures_mapped;
   1030       break;
   1031    case SVGA_QUERY_NUM_BYTES_UPLOADED:
   1032       sq->end_count = svga->hud.num_bytes_uploaded;
   1033       break;
   1034    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
   1035       sq->end_count = svga->hud.command_buffer_size;
   1036       break;
   1037    case SVGA_QUERY_FLUSH_TIME:
   1038       sq->end_count = svga->hud.flush_time;
   1039       break;
   1040    case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
   1041       sq->end_count = svga->hud.surface_write_flushes;
   1042       break;
   1043    case SVGA_QUERY_NUM_READBACKS:
   1044       sq->end_count = svga->hud.num_readbacks;
   1045       break;
   1046    case SVGA_QUERY_NUM_RESOURCE_UPDATES:
   1047       sq->end_count = svga->hud.num_resource_updates;
   1048       break;
   1049    case SVGA_QUERY_NUM_BUFFER_UPLOADS:
   1050       sq->end_count = svga->hud.num_buffer_uploads;
   1051       break;
   1052    case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
   1053       sq->end_count = svga->hud.num_const_buf_updates;
   1054       break;
   1055    case SVGA_QUERY_NUM_CONST_UPDATES:
   1056       sq->end_count = svga->hud.num_const_updates;
   1057       break;
   1058    case SVGA_QUERY_MEMORY_USED:
   1059    case SVGA_QUERY_NUM_SHADERS:
   1060    case SVGA_QUERY_NUM_RESOURCES:
   1061    case SVGA_QUERY_NUM_STATE_OBJECTS:
   1062    case SVGA_QUERY_NUM_SURFACE_VIEWS:
   1063    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
   1064    case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
   1065    case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
   1066       /* nothing */
   1067       break;
   1068    default:
   1069       assert(!"unexpected query type in svga_end_query()");
   1070    }
   1071    svga->sq[sq->type] = NULL;
   1072    return true;
   1073 }
   1074 
   1075 
   1076 static boolean
   1077 svga_get_query_result(struct pipe_context *pipe,
   1078                       struct pipe_query *q,
   1079                       boolean wait,
   1080                       union pipe_query_result *vresult)
   1081 {
   1082    struct svga_screen *svgascreen = svga_screen(pipe->screen);
   1083    struct svga_context *svga = svga_context(pipe);
   1084    struct svga_query *sq = svga_query(q);
   1085    uint64_t *result = (uint64_t *)vresult;
   1086    boolean ret = TRUE;
   1087 
   1088    assert(sq);
   1089 
   1090    SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d wait: %d\n",
   1091             __FUNCTION__, sq, sq->id, wait);
   1092 
   1093    switch (sq->type) {
   1094    case PIPE_QUERY_OCCLUSION_COUNTER:
   1095       if (svga_have_vgpu10(svga)) {
   1096          SVGADXOcclusionQueryResult occResult;
   1097          ret = get_query_result_vgpu10(svga, sq, wait,
   1098                                        (void *)&occResult, sizeof(occResult));
   1099          *result = (uint64_t)occResult.samplesRendered;
   1100       } else {
   1101          ret = get_query_result_vgpu9(svga, sq, wait, result);
   1102       }
   1103       break;
   1104    case PIPE_QUERY_OCCLUSION_PREDICATE:
   1105    case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: {
   1106       if (svga_have_vgpu10(svga)) {
   1107          SVGADXOcclusionPredicateQueryResult occResult;
   1108          ret = get_query_result_vgpu10(svga, sq, wait,
   1109                                        (void *)&occResult, sizeof(occResult));
   1110          vresult->b = occResult.anySamplesRendered != 0;
   1111       } else {
   1112          uint64_t count = 0;
   1113          ret = get_query_result_vgpu9(svga, sq, wait, &count);
   1114          vresult->b = count != 0;
   1115       }
   1116       break;
   1117    }
   1118    case PIPE_QUERY_SO_STATISTICS: {
   1119       SVGADXStreamOutStatisticsQueryResult sResult;
   1120       struct pipe_query_data_so_statistics *pResult =
   1121          (struct pipe_query_data_so_statistics *)vresult;
   1122 
   1123       assert(svga_have_vgpu10(svga));
   1124       ret = get_query_result_vgpu10(svga, sq, wait,
   1125                                     (void *)&sResult, sizeof(sResult));
   1126       pResult->num_primitives_written = sResult.numPrimitivesWritten;
   1127       pResult->primitives_storage_needed = sResult.numPrimitivesRequired;
   1128       break;
   1129    }
   1130    case PIPE_QUERY_TIMESTAMP: {
   1131       SVGADXTimestampQueryResult sResult;
   1132 
   1133       assert(svga_have_vgpu10(svga));
   1134       ret = get_query_result_vgpu10(svga, sq, wait,
   1135                                     (void *)&sResult, sizeof(sResult));
   1136       *result = (uint64_t)sResult.timestamp;
   1137       break;
   1138    }
   1139    case PIPE_QUERY_PRIMITIVES_GENERATED: {
   1140       SVGADXStreamOutStatisticsQueryResult sResult;
   1141 
   1142       assert(svga_have_vgpu10(svga));
   1143       ret = get_query_result_vgpu10(svga, sq, wait,
   1144                                     (void *)&sResult, sizeof sResult);
   1145       *result = (uint64_t)sResult.numPrimitivesRequired;
   1146       break;
   1147    }
   1148    case PIPE_QUERY_PRIMITIVES_EMITTED: {
   1149       SVGADXStreamOutStatisticsQueryResult sResult;
   1150 
   1151       assert(svga_have_vgpu10(svga));
   1152       ret = get_query_result_vgpu10(svga, sq, wait,
   1153                                     (void *)&sResult, sizeof sResult);
   1154       *result = (uint64_t)sResult.numPrimitivesWritten;
   1155       break;
   1156    }
   1157    /* These are per-frame counters */
   1158    case SVGA_QUERY_NUM_DRAW_CALLS:
   1159    case SVGA_QUERY_NUM_FALLBACKS:
   1160    case SVGA_QUERY_NUM_FLUSHES:
   1161    case SVGA_QUERY_NUM_VALIDATIONS:
   1162    case SVGA_QUERY_MAP_BUFFER_TIME:
   1163    case SVGA_QUERY_NUM_BUFFERS_MAPPED:
   1164    case SVGA_QUERY_NUM_TEXTURES_MAPPED:
   1165    case SVGA_QUERY_NUM_BYTES_UPLOADED:
   1166    case SVGA_QUERY_COMMAND_BUFFER_SIZE:
   1167    case SVGA_QUERY_FLUSH_TIME:
   1168    case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
   1169    case SVGA_QUERY_NUM_READBACKS:
   1170    case SVGA_QUERY_NUM_RESOURCE_UPDATES:
   1171    case SVGA_QUERY_NUM_BUFFER_UPLOADS:
   1172    case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
   1173    case SVGA_QUERY_NUM_CONST_UPDATES:
   1174       vresult->u64 = sq->end_count - sq->begin_count;
   1175       break;
   1176    /* These are running total counters */
   1177    case SVGA_QUERY_MEMORY_USED:
   1178       vresult->u64 = svgascreen->hud.total_resource_bytes;
   1179       break;
   1180    case SVGA_QUERY_NUM_SHADERS:
   1181       vresult->u64 = svga->hud.num_shaders;
   1182       break;
   1183    case SVGA_QUERY_NUM_RESOURCES:
   1184       vresult->u64 = svgascreen->hud.num_resources;
   1185       break;
   1186    case SVGA_QUERY_NUM_STATE_OBJECTS:
   1187       vresult->u64 = (svga->hud.num_blend_objects +
   1188                       svga->hud.num_depthstencil_objects +
   1189                       svga->hud.num_rasterizer_objects +
   1190                       svga->hud.num_sampler_objects +
   1191                       svga->hud.num_samplerview_objects +
   1192                       svga->hud.num_vertexelement_objects);
   1193       break;
   1194    case SVGA_QUERY_NUM_SURFACE_VIEWS:
   1195       vresult->u64 = svga->hud.num_surface_views;
   1196       break;
   1197    case SVGA_QUERY_NUM_GENERATE_MIPMAP:
   1198       vresult->u64 = svga->hud.num_generate_mipmap;
   1199       break;
   1200    case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
   1201       vresult->u64 = svgascreen->hud.num_failed_allocations;
   1202       break;
   1203    case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
   1204       vresult->f = (float) svga->swc->num_commands
   1205          / (float) svga->swc->num_draw_commands;
   1206       break;
   1207    default:
   1208       assert(!"unexpected query type in svga_get_query_result");
   1209    }
   1210 
   1211    SVGA_DBG(DEBUG_QUERY, "%s result %d\n", __FUNCTION__, *((uint64_t *)vresult));
   1212 
   1213    return ret;
   1214 }
   1215 
   1216 static void
   1217 svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
   1218                       boolean condition, enum pipe_render_cond_flag mode)
   1219 {
   1220    struct svga_context *svga = svga_context(pipe);
   1221    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   1222    struct svga_query *sq = svga_query(q);
   1223    SVGA3dQueryId queryId;
   1224    enum pipe_error ret;
   1225 
   1226    SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
   1227 
   1228    assert(svga_have_vgpu10(svga));
   1229    if (sq == NULL) {
   1230       queryId = SVGA3D_INVALID_ID;
   1231    }
   1232    else {
   1233       assert(sq->svga_type == SVGA3D_QUERYTYPE_OCCLUSION ||
   1234              sq->svga_type == SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE);
   1235 
   1236       if (sq->svga_type == SVGA3D_QUERYTYPE_OCCLUSION) {
   1237          assert(sq->predicate);
   1238          /**
   1239           * For conditional rendering, make sure to use the associated
   1240           * predicate query.
   1241           */
   1242          sq = svga_query(sq->predicate);
   1243       }
   1244       queryId = sq->id;
   1245 
   1246       if ((mode == PIPE_RENDER_COND_WAIT ||
   1247            mode == PIPE_RENDER_COND_BY_REGION_WAIT) && sq->fence) {
   1248          sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
   1249                            SVGA_FENCE_FLAG_QUERY);
   1250       }
   1251    }
   1252    /*
   1253     * if the kernel module doesn't support the predication command,
   1254     * we'll just render unconditionally.
   1255     * This is probably acceptable for the typical case of occlusion culling.
   1256     */
   1257    if (sws->have_set_predication_cmd) {
   1258       ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
   1259                                          (uint32) condition);
   1260       if (ret != PIPE_OK) {
   1261          svga_context_flush(svga, NULL);
   1262          ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
   1263                                             (uint32) condition);
   1264       }
   1265       svga->pred.query_id = queryId;
   1266       svga->pred.cond = condition;
   1267    }
   1268 
   1269    svga->render_condition = (sq != NULL);
   1270 }
   1271 
   1272 
   1273 /*
   1274  * This function is a workaround because we lack the ability to query
   1275  * renderer's time synchornously.
   1276  */
   1277 static uint64_t
   1278 svga_get_timestamp(struct pipe_context *pipe)
   1279 {
   1280    struct pipe_query *q = svga_create_query(pipe, PIPE_QUERY_TIMESTAMP, 0);
   1281    union pipe_query_result result;
   1282 
   1283    svga_begin_query(pipe, q);
   1284    svga_end_query(pipe,q);
   1285    svga_get_query_result(pipe, q, TRUE, &result);
   1286    svga_destroy_query(pipe, q);
   1287 
   1288    return result.u64;
   1289 }
   1290 
   1291 
   1292 static void
   1293 svga_set_active_query_state(struct pipe_context *pipe, boolean enable)
   1294 {
   1295 }
   1296 
   1297 
   1298 /**
   1299  * \brief Toggle conditional rendering if already enabled
   1300  *
   1301  * \param svga[in]  The svga context
   1302  * \param render_condition_enabled[in]  Whether to ignore requests to turn
   1303  * conditional rendering off
   1304  * \param on[in]  Whether to turn conditional rendering on or off
   1305  */
   1306 void
   1307 svga_toggle_render_condition(struct svga_context *svga,
   1308                              boolean render_condition_enabled,
   1309                              boolean on)
   1310 {
   1311    SVGA3dQueryId query_id;
   1312    enum pipe_error ret;
   1313 
   1314    if (render_condition_enabled ||
   1315        svga->pred.query_id == SVGA3D_INVALID_ID) {
   1316       return;
   1317    }
   1318 
   1319    /*
   1320     * If we get here, it means that the system supports
   1321     * conditional rendering since svga->pred.query_id has already been
   1322     * modified for this context and thus support has already been
   1323     * verified.
   1324     */
   1325    query_id = on ? svga->pred.query_id : SVGA3D_INVALID_ID;
   1326 
   1327    ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
   1328                                       (uint32) svga->pred.cond);
   1329    if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
   1330       svga_context_flush(svga, NULL);
   1331       ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
   1332                                          (uint32) svga->pred.cond);
   1333       assert(ret == PIPE_OK);
   1334    }
   1335 }
   1336 
   1337 
   1338 void
   1339 svga_init_query_functions(struct svga_context *svga)
   1340 {
   1341    svga->pipe.create_query = svga_create_query;
   1342    svga->pipe.destroy_query = svga_destroy_query;
   1343    svga->pipe.begin_query = svga_begin_query;
   1344    svga->pipe.end_query = svga_end_query;
   1345    svga->pipe.get_query_result = svga_get_query_result;
   1346    svga->pipe.set_active_query_state = svga_set_active_query_state;
   1347    svga->pipe.render_condition = svga_render_condition;
   1348    svga->pipe.get_timestamp = svga_get_timestamp;
   1349 }
   1350