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