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