SVGA3dQueryType svga_type; /**< SVGA3D_QUERYTYPE_x or unused */
unsigned id; /** Per-context query identifier */
+ boolean active; /** TRUE if query is active */
struct pipe_fence_handle *fence;
* VGPU9
*/
-static boolean
+static bool
svga_get_query_result(struct pipe_context *pipe,
struct pipe_query *q,
- boolean wait,
+ bool wait,
union pipe_query_result *result);
static enum pipe_error
return PIPE_OK;
}
-static enum pipe_error
+static void
begin_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
{
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
- enum pipe_error ret = PIPE_OK;
if (sq->queryResult->state == SVGA3D_QUERYSTATE_PENDING) {
/* The application doesn't care for the pending query result.
sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
sws->fence_reference(sws, &sq->fence, NULL);
- ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type);
- }
- return ret;
+ SVGA_RETRY(svga, SVGA3D_BeginQuery(svga->swc, sq->svga_type));
}
-static enum pipe_error
+static void
end_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
{
- enum pipe_error ret = PIPE_OK;
-
/* Set to PENDING before sending EndQuery. */
sq->queryResult->state = SVGA3D_QUERYSTATE_PENDING;
- ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf);
- }
- return ret;
+ SVGA_RETRY(svga, SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf));
}
-static boolean
+static bool
get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
- boolean wait, uint64_t *result)
+ bool wait, uint64_t *result)
{
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
- enum pipe_error ret;
SVGA3dQueryState state;
if (!sq->fence) {
* SVGA_3D_CMD_WAIT_FOR_QUERY is emitted. Unfortunately this will cause
* a synchronous wait on the host.
*/
- ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf);
- }
- assert (ret == PIPE_OK);
+ SVGA_RETRY(svga, SVGA3D_WaitForQuery(svga->swc, sq->svga_type,
+ sq->hwbuf));
svga_context_flush(svga, &sq->fence);
assert(sq->fence);
}
state = sq->queryResult->state;
if (state == SVGA3D_QUERYSTATE_PENDING) {
if (!wait)
- return FALSE;
- sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
+ return false;
+ sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
+ SVGA_FENCE_FLAG_QUERY);
state = sq->queryResult->state;
}
state == SVGA3D_QUERYSTATE_FAILED);
*result = (uint64_t)sq->queryResult->result32;
- return TRUE;
+ return true;
}
* will hold queries of the same type. Multiple memory blocks can be allocated
* for a particular query type.
*
- * Currently each memory block is of 184 bytes. We support up to 128
+ * Currently each memory block is of 184 bytes. We support up to 512
* memory blocks. The query memory size is arbitrary right now.
* Each occlusion query takes about 8 bytes. One memory block can accomodate
- * 23 occlusion queries. 128 of those blocks can support up to 2944 occlusion
+ * 23 occlusion queries. 512 of those blocks can support up to 11K occlusion
* queries. That seems reasonable for now. If we think this limit is
* not enough, we can increase the limit or try to grow the mob in runtime.
* Note, SVGA device does not impose one mob per context for queries,
* following commands: DXMoveQuery, DXBindAllQuery & DXReadbackAllQuery.
*/
#define SVGA_QUERY_MEM_BLOCK_SIZE (sizeof(SVGADXQueryResultUnion) * 2)
-#define SVGA_QUERY_MEM_SIZE (128 * SVGA_QUERY_MEM_BLOCK_SIZE)
+#define SVGA_QUERY_MEM_SIZE (512 * SVGA_QUERY_MEM_BLOCK_SIZE)
struct svga_qmem_alloc_entry
{
/**
* Allocate a memory block from the query object memory
- * \return -1 if out of memory, else index of the query memory block
+ * \return NULL if out of memory, else pointer to the query memory block
*/
-static int
+static struct svga_qmem_alloc_entry *
allocate_query_block(struct svga_context *svga)
{
int index;
unsigned offset;
+ struct svga_qmem_alloc_entry *alloc_entry = NULL;
/* Find the next available query block */
index = util_bitmask_add(svga->gb_query_alloc_mask);
if (index == UTIL_BITMASK_INVALID_INDEX)
- return -1;
+ return NULL;
offset = index * SVGA_QUERY_MEM_BLOCK_SIZE;
if (offset >= svga->gb_query_len) {
unsigned i;
+ /* Deallocate the out-of-range index */
+ util_bitmask_clear(svga->gb_query_alloc_mask, index);
+ index = -1;
+
/**
* All the memory blocks are allocated, lets see if there is
* any empty memory block around that can be freed up.
*/
- index = -1;
- for (i = 0; i < SVGA_QUERY_MAX && index == -1; i++) {
- struct svga_qmem_alloc_entry *alloc_entry;
+ for (i = 0; i < SVGA3D_QUERYTYPE_MAX && index == -1; i++) {
struct svga_qmem_alloc_entry *prev_alloc_entry = NULL;
alloc_entry = svga->gb_query_map[i];
}
}
}
+
+ if (index == -1) {
+ debug_printf("Query memory object is full\n");
+ return NULL;
+ }
}
- return index;
+ if (!alloc_entry) {
+ assert(index != -1);
+ alloc_entry = CALLOC_STRUCT(svga_qmem_alloc_entry);
+ alloc_entry->block_index = index;
+ }
+
+ return alloc_entry;
}
/**
unsigned len)
{
struct svga_qmem_alloc_entry *alloc_entry;
- int block_index = -1;
- block_index = allocate_query_block(svga);
- if (block_index == -1)
- return NULL;
- alloc_entry = CALLOC_STRUCT(svga_qmem_alloc_entry);
+ alloc_entry = allocate_query_block(svga);
if (!alloc_entry)
return NULL;
- alloc_entry->block_index = block_index;
- alloc_entry->start_offset = block_index * SVGA_QUERY_MEM_BLOCK_SIZE;
+ assert(alloc_entry->block_index != -1);
+ alloc_entry->start_offset =
+ alloc_entry->block_index * SVGA_QUERY_MEM_BLOCK_SIZE;
alloc_entry->nquery = 0;
alloc_entry->alloc_mask = util_bitmask_create();
alloc_entry->next = NULL;
int slot_index = -1;
unsigned offset;
- assert(type < SVGA_QUERY_MAX);
+ assert(type < SVGA3D_QUERYTYPE_MAX);
alloc_entry = svga->gb_query_map[type];
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
unsigned i;
- for (i = 0; i < SVGA_QUERY_MAX; i++) {
+ for (i = 0; i < SVGA3D_QUERYTYPE_MAX; i++) {
struct svga_qmem_alloc_entry *alloc_entry, *next;
alloc_entry = svga->gb_query_map[i];
while (alloc_entry) {
svga->gb_query_alloc_mask = util_bitmask_create();
/* Bind the query object to the context */
- if (svga->swc->query_bind(svga->swc, svga->gb_query,
- SVGA_QUERY_FLAG_SET) != PIPE_OK) {
- svga_context_flush(svga, NULL);
- svga->swc->query_bind(svga->swc, svga->gb_query,
- SVGA_QUERY_FLAG_SET);
- }
+ SVGA_RETRY(svga, svga->swc->query_bind(svga->swc, svga->gb_query,
+ SVGA_QUERY_FLAG_SET));
}
sq->gb_query = svga->gb_query;
- /* Allocate an integer ID for this query */
- sq->id = util_bitmask_add(svga->query_id_bm);
- if (sq->id == UTIL_BITMASK_INVALID_INDEX)
- return PIPE_ERROR_OUT_OF_MEMORY;
+ /* Make sure query length is in multiples of 8 bytes */
+ qlen = align(resultLen + sizeof(SVGA3dQueryState), 8);
/* Find a slot for this query in the gb object */
- qlen = resultLen + sizeof(SVGA3dQueryState);
sq->offset = allocate_query(svga, sq->svga_type, qlen);
if (sq->offset == -1)
return PIPE_ERROR_OUT_OF_MEMORY;
+ assert((sq->offset & 7) == 0);
+
SVGA_DBG(DEBUG_QUERY, " query type=%d qid=0x%x offset=%d\n",
sq->svga_type, sq->id, sq->offset);
/**
* Send SVGA3D commands to define the query
*/
- ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
- }
+ SVGA_RETRY_OOM(svga, ret, SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id,
+ sq->svga_type,
+ sq->flags));
if (ret != PIPE_OK)
return PIPE_ERROR_OUT_OF_MEMORY;
- ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
- }
- assert(ret == PIPE_OK);
-
- ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
- }
- assert(ret == PIPE_OK);
+ SVGA_RETRY(svga, SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id));
+ SVGA_RETRY(svga, SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id,
+ sq->offset));
return PIPE_OK;
}
-static enum pipe_error
+static void
destroy_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
{
- enum pipe_error ret;
-
- ret = SVGA3D_vgpu10_DestroyQuery(svga->swc, sq->id);
+ SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyQuery(svga->swc, sq->id));
/* Deallocate the memory slot allocated for this query */
deallocate_query(svga, sq);
-
- return ret;
}
static void
rebind_vgpu10_query(struct svga_context *svga)
{
- if (svga->swc->query_bind(svga->swc, svga->gb_query,
- SVGA_QUERY_FLAG_REF) != PIPE_OK) {
- svga_context_flush(svga, NULL);
- svga->swc->query_bind(svga->swc, svga->gb_query,
- SVGA_QUERY_FLAG_REF);
- }
-
+ SVGA_RETRY(svga, svga->swc->query_bind(svga->swc, svga->gb_query,
+ SVGA_QUERY_FLAG_REF));
svga->rebind.flags.query = FALSE;
}
begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
{
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
- enum pipe_error ret = PIPE_OK;
int status = 0;
sws->fence_reference(sws, &sq->fence, NULL);
}
/* Send the BeginQuery command to the device */
- ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
- }
- return ret;
+ SVGA_RETRY(svga, SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id));
+ return PIPE_OK;
}
-static enum pipe_error
+static void
end_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
{
- enum pipe_error ret = PIPE_OK;
-
if (svga->rebind.flags.query) {
rebind_vgpu10_query(svga);
}
- ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
- }
-
- return ret;
+ SVGA_RETRY(svga, SVGA3D_vgpu10_EndQuery(svga->swc, sq->id));
}
-static boolean
+static bool
get_query_result_vgpu10(struct svga_context *svga, struct svga_query *sq,
- boolean wait, void *result, int resultLen)
+ bool wait, void *result, int resultLen)
{
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
SVGA3dQueryState queryState;
sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);
- if (!sq->fence) {
- /* The query hasn't been submitted yet. We need to submit it now
- * since the GL spec says "Querying the state for a given occlusion
- * query forces that occlusion query to complete within a finite amount
- * of time."
+ if (queryState != SVGA3D_QUERYSTATE_SUCCEEDED && !sq->fence) {
+ /* We don't have the query result yet, and the query hasn't been
+ * submitted. We need to submit it now since the GL spec says
+ * "Querying the state for a given occlusion query forces that
+ * occlusion query to complete within a finite amount of time."
*/
svga_context_flush(svga, &sq->fence);
}
if (queryState == SVGA3D_QUERYSTATE_PENDING ||
queryState == SVGA3D_QUERYSTATE_NEW) {
if (!wait)
- return FALSE;
- sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
+ return false;
+ sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
+ SVGA_FENCE_FLAG_QUERY);
sws->query_get_result(sws, sq->gb_query, sq->offset, &queryState, result, resultLen);
}
assert(queryState == SVGA3D_QUERYSTATE_SUCCEEDED ||
queryState == SVGA3D_QUERYSTATE_FAILED);
- return TRUE;
+ return true;
}
static struct pipe_query *
{
struct svga_context *svga = svga_context(pipe);
struct svga_query *sq;
+ enum pipe_error ret;
assert(query_type < SVGA_QUERY_MAX);
case PIPE_QUERY_OCCLUSION_COUNTER:
sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION;
if (svga_have_vgpu10(svga)) {
- define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionQueryResult));
+ ret = define_query_vgpu10(svga, sq,
+ sizeof(SVGADXOcclusionQueryResult));
+ if (ret != PIPE_OK)
+ goto fail;
/**
* In OpenGL, occlusion counter query can be used in conditional
sq->predicate = svga_create_query(pipe, PIPE_QUERY_OCCLUSION_PREDICATE, index);
} else {
- define_query_vgpu9(svga, sq);
+ ret = define_query_vgpu9(svga, sq);
+ if (ret != PIPE_OK)
+ goto fail;
}
break;
case PIPE_QUERY_OCCLUSION_PREDICATE:
+ case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
if (svga_have_vgpu10(svga)) {
sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE;
- define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionPredicateQueryResult));
+ ret = define_query_vgpu10(svga, sq,
+ sizeof(SVGADXOcclusionPredicateQueryResult));
+ if (ret != PIPE_OK)
+ goto fail;
} else {
sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSION;
- define_query_vgpu9(svga, sq);
+ ret = define_query_vgpu9(svga, sq);
+ if (ret != PIPE_OK)
+ goto fail;
}
break;
case PIPE_QUERY_PRIMITIVES_GENERATED:
case PIPE_QUERY_PRIMITIVES_EMITTED:
case PIPE_QUERY_SO_STATISTICS:
assert(svga_have_vgpu10(svga));
- sq->svga_type = SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS;
- define_query_vgpu10(svga, sq,
- sizeof(SVGADXStreamOutStatisticsQueryResult));
+
+ /* Until the device supports the new query type for multiple streams,
+ * we will use the single stream query type for stream 0.
+ */
+ if (svga_have_sm5(svga) && index > 0) {
+ assert(index < 4);
+
+ sq->svga_type = SVGA3D_QUERYTYPE_SOSTATS_STREAM0 + index;
+ }
+ else {
+ assert(index == 0);
+ sq->svga_type = SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS;
+ }
+ ret = define_query_vgpu10(svga, sq,
+ sizeof(SVGADXStreamOutStatisticsQueryResult));
+ if (ret != PIPE_OK)
+ goto fail;
break;
case PIPE_QUERY_TIMESTAMP:
assert(svga_have_vgpu10(svga));
sq->svga_type = SVGA3D_QUERYTYPE_TIMESTAMP;
- define_query_vgpu10(svga, sq,
- sizeof(SVGADXTimestampQueryResult));
+ ret = define_query_vgpu10(svga, sq,
+ sizeof(SVGADXTimestampQueryResult));
+ if (ret != PIPE_OK)
+ goto fail;
break;
case SVGA_QUERY_NUM_DRAW_CALLS:
case SVGA_QUERY_NUM_FALLBACKS:
case SVGA_QUERY_NUM_FLUSHES:
case SVGA_QUERY_NUM_VALIDATIONS:
- case SVGA_QUERY_NUM_RESOURCES_MAPPED:
+ case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+ case SVGA_QUERY_NUM_TEXTURES_MAPPED:
case SVGA_QUERY_NUM_BYTES_UPLOADED:
+ case SVGA_QUERY_NUM_COMMAND_BUFFERS:
case SVGA_QUERY_COMMAND_BUFFER_SIZE:
case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
case SVGA_QUERY_MEMORY_USED:
case SVGA_QUERY_NUM_BUFFER_UPLOADS:
case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
case SVGA_QUERY_NUM_CONST_UPDATES:
+ case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+ case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+ case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+ case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
+ case SVGA_QUERY_SHADER_MEM_USED:
break;
case SVGA_QUERY_FLUSH_TIME:
case SVGA_QUERY_MAP_BUFFER_TIME:
/* These queries need os_time_get() */
svga->hud.uses_time = TRUE;
break;
+
default:
assert(!"unexpected query type in svga_create_query()");
}
switch (sq->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
+ case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
if (svga_have_vgpu10(svga)) {
/* make sure to also destroy any associated predicate query */
if (sq->predicate)
case SVGA_QUERY_NUM_FLUSHES:
case SVGA_QUERY_NUM_VALIDATIONS:
case SVGA_QUERY_MAP_BUFFER_TIME:
- case SVGA_QUERY_NUM_RESOURCES_MAPPED:
+ case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+ case SVGA_QUERY_NUM_TEXTURES_MAPPED:
case SVGA_QUERY_NUM_BYTES_UPLOADED:
+ case SVGA_QUERY_NUM_COMMAND_BUFFERS:
case SVGA_QUERY_COMMAND_BUFFER_SIZE:
case SVGA_QUERY_FLUSH_TIME:
case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
case SVGA_QUERY_NUM_BUFFER_UPLOADS:
case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
case SVGA_QUERY_NUM_CONST_UPDATES:
+ case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+ case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+ case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+ case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
+ case SVGA_QUERY_SHADER_MEM_USED:
/* nothing */
break;
default:
}
-static boolean
+static bool
svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
{
struct svga_context *svga = svga_context(pipe);
struct svga_query *sq = svga_query(q);
- enum pipe_error ret;
+ enum pipe_error ret = PIPE_OK;
assert(sq);
assert(sq->type < SVGA_QUERY_MAX);
- SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
- sq, sq->id);
-
/* Need to flush out buffered drawing commands so that they don't
* get counted in the query results.
*/
switch (sq->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
+ case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
if (svga_have_vgpu10(svga)) {
ret = begin_query_vgpu10(svga, sq);
/* also need to start the associated occlusion predicate query */
(void) status;
}
} else {
- ret = begin_query_vgpu9(svga, sq);
+ begin_query_vgpu9(svga, sq);
}
assert(ret == PIPE_OK);
(void) ret;
case SVGA_QUERY_MAP_BUFFER_TIME:
sq->begin_count = svga->hud.map_buffer_time;
break;
- case SVGA_QUERY_NUM_RESOURCES_MAPPED:
- sq->begin_count = svga->hud.num_resources_mapped;
+ case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+ sq->begin_count = svga->hud.num_buffers_mapped;
+ break;
+ case SVGA_QUERY_NUM_TEXTURES_MAPPED:
+ sq->begin_count = svga->hud.num_textures_mapped;
break;
case SVGA_QUERY_NUM_BYTES_UPLOADED:
sq->begin_count = svga->hud.num_bytes_uploaded;
break;
+ case SVGA_QUERY_NUM_COMMAND_BUFFERS:
+ sq->begin_count = svga->swc->num_command_buffers;
+ break;
case SVGA_QUERY_COMMAND_BUFFER_SIZE:
sq->begin_count = svga->hud.command_buffer_size;
break;
case SVGA_QUERY_NUM_CONST_UPDATES:
sq->begin_count = svga->hud.num_const_updates;
break;
+ case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+ sq->begin_count = svga->swc->num_shader_reloc;
+ break;
+ case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
+ sq->begin_count = svga->swc->num_surf_reloc;
+ break;
case SVGA_QUERY_MEMORY_USED:
case SVGA_QUERY_NUM_SHADERS:
case SVGA_QUERY_NUM_RESOURCES:
case SVGA_QUERY_NUM_STATE_OBJECTS:
case SVGA_QUERY_NUM_SURFACE_VIEWS:
case SVGA_QUERY_NUM_GENERATE_MIPMAP:
+ case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+ case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+ case SVGA_QUERY_SHADER_MEM_USED:
/* nothing */
break;
default:
assert(!"unexpected query type in svga_begin_query()");
}
- svga->sq[sq->type] = sq;
+ SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d type=%d svga_type=%d\n",
+ __FUNCTION__, sq, sq->id, sq->type, sq->svga_type);
+
+ sq->active = TRUE;
return true;
}
{
struct svga_context *svga = svga_context(pipe);
struct svga_query *sq = svga_query(q);
- enum pipe_error ret;
assert(sq);
assert(sq->type < SVGA_QUERY_MAX);
- SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
- sq, sq->id);
+ SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x type=%d\n",
+ __FUNCTION__, sq, sq->type);
- if (sq->type == PIPE_QUERY_TIMESTAMP && svga->sq[sq->type] != sq)
+ if (sq->type == PIPE_QUERY_TIMESTAMP && !sq->active)
svga_begin_query(pipe, q);
+ SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d type=%d svga_type=%d\n",
+ __FUNCTION__, sq, sq->id, sq->type, sq->svga_type);
+
svga_hwtnl_flush_retry(svga);
- assert(svga->sq[sq->type] == sq);
+ assert(sq->active);
switch (sq->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
+ case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
if (svga_have_vgpu10(svga)) {
- ret = end_query_vgpu10(svga, sq);
+ end_query_vgpu10(svga, sq);
/* also need to end the associated occlusion predicate query */
if (sq->predicate) {
- enum pipe_error status;
- status = end_query_vgpu10(svga, svga_query(sq->predicate));
- assert(status == PIPE_OK);
- (void) status;
+ end_query_vgpu10(svga, svga_query(sq->predicate));
}
} else {
- ret = end_query_vgpu9(svga, sq);
+ end_query_vgpu9(svga, sq);
}
- assert(ret == PIPE_OK);
- (void) ret;
- /* TODO: Delay flushing. We don't really need to flush here, just ensure
- * that there is one flush before svga_get_query_result attempts to get
- * the result.
- */
- svga_context_flush(svga, NULL);
break;
case PIPE_QUERY_PRIMITIVES_GENERATED:
case PIPE_QUERY_PRIMITIVES_EMITTED:
case PIPE_QUERY_SO_STATISTICS:
case PIPE_QUERY_TIMESTAMP:
assert(svga_have_vgpu10(svga));
- ret = end_query_vgpu10(svga, sq);
- assert(ret == PIPE_OK);
+ end_query_vgpu10(svga, sq);
break;
case SVGA_QUERY_NUM_DRAW_CALLS:
sq->end_count = svga->hud.num_draw_calls;
case SVGA_QUERY_MAP_BUFFER_TIME:
sq->end_count = svga->hud.map_buffer_time;
break;
- case SVGA_QUERY_NUM_RESOURCES_MAPPED:
- sq->end_count = svga->hud.num_resources_mapped;
+ case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+ sq->end_count = svga->hud.num_buffers_mapped;
+ break;
+ case SVGA_QUERY_NUM_TEXTURES_MAPPED:
+ sq->end_count = svga->hud.num_textures_mapped;
break;
case SVGA_QUERY_NUM_BYTES_UPLOADED:
sq->end_count = svga->hud.num_bytes_uploaded;
break;
+ case SVGA_QUERY_NUM_COMMAND_BUFFERS:
+ sq->end_count = svga->swc->num_command_buffers;
+ break;
case SVGA_QUERY_COMMAND_BUFFER_SIZE:
sq->end_count = svga->hud.command_buffer_size;
break;
case SVGA_QUERY_NUM_CONST_UPDATES:
sq->end_count = svga->hud.num_const_updates;
break;
+ case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+ sq->end_count = svga->swc->num_shader_reloc;
+ break;
+ case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
+ sq->end_count = svga->swc->num_surf_reloc;
+ break;
case SVGA_QUERY_MEMORY_USED:
case SVGA_QUERY_NUM_SHADERS:
case SVGA_QUERY_NUM_RESOURCES:
case SVGA_QUERY_NUM_STATE_OBJECTS:
case SVGA_QUERY_NUM_SURFACE_VIEWS:
case SVGA_QUERY_NUM_GENERATE_MIPMAP:
+ case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+ case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+ case SVGA_QUERY_SHADER_MEM_USED:
/* nothing */
break;
default:
assert(!"unexpected query type in svga_end_query()");
}
- svga->sq[sq->type] = NULL;
+ sq->active = FALSE;
return true;
}
-static boolean
+static bool
svga_get_query_result(struct pipe_context *pipe,
struct pipe_query *q,
- boolean wait,
+ bool wait,
union pipe_query_result *vresult)
{
struct svga_screen *svgascreen = svga_screen(pipe->screen);
struct svga_context *svga = svga_context(pipe);
struct svga_query *sq = svga_query(q);
uint64_t *result = (uint64_t *)vresult;
- boolean ret = TRUE;
+ bool ret = true;
assert(sq);
ret = get_query_result_vgpu9(svga, sq, wait, result);
}
break;
- case PIPE_QUERY_OCCLUSION_PREDICATE: {
+ case PIPE_QUERY_OCCLUSION_PREDICATE:
+ case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: {
if (svga_have_vgpu10(svga)) {
SVGADXOcclusionPredicateQueryResult occResult;
ret = get_query_result_vgpu10(svga, sq, wait,
case SVGA_QUERY_NUM_FLUSHES:
case SVGA_QUERY_NUM_VALIDATIONS:
case SVGA_QUERY_MAP_BUFFER_TIME:
- case SVGA_QUERY_NUM_RESOURCES_MAPPED:
+ case SVGA_QUERY_NUM_BUFFERS_MAPPED:
+ case SVGA_QUERY_NUM_TEXTURES_MAPPED:
case SVGA_QUERY_NUM_BYTES_UPLOADED:
+ case SVGA_QUERY_NUM_COMMAND_BUFFERS:
case SVGA_QUERY_COMMAND_BUFFER_SIZE:
case SVGA_QUERY_FLUSH_TIME:
case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
case SVGA_QUERY_NUM_BUFFER_UPLOADS:
case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
case SVGA_QUERY_NUM_CONST_UPDATES:
+ case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
+ case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
vresult->u64 = sq->end_count - sq->begin_count;
break;
/* These are running total counters */
case SVGA_QUERY_NUM_GENERATE_MIPMAP:
vresult->u64 = svga->hud.num_generate_mipmap;
break;
+ case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
+ vresult->u64 = svgascreen->hud.num_failed_allocations;
+ break;
+ case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
+ vresult->f = (float) svga->swc->num_commands
+ / (float) svga->swc->num_draw_commands;
+ break;
+ case SVGA_QUERY_SHADER_MEM_USED:
+ vresult->u64 = svga->hud.shader_mem_used;
+ break;
default:
assert(!"unexpected query type in svga_get_query_result");
}
static void
svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
- boolean condition, uint mode)
+ bool condition, enum pipe_render_cond_flag mode)
{
struct svga_context *svga = svga_context(pipe);
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
struct svga_query *sq = svga_query(q);
SVGA3dQueryId queryId;
- enum pipe_error ret;
SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
if ((mode == PIPE_RENDER_COND_WAIT ||
mode == PIPE_RENDER_COND_BY_REGION_WAIT) && sq->fence) {
- sws->fence_finish(sws, sq->fence, SVGA_FENCE_FLAG_QUERY);
+ sws->fence_finish(sws, sq->fence, PIPE_TIMEOUT_INFINITE,
+ SVGA_FENCE_FLAG_QUERY);
}
}
/*
* This is probably acceptable for the typical case of occlusion culling.
*/
if (sws->have_set_predication_cmd) {
- ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
- (uint32) condition);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
- (uint32) condition);
- }
+ SVGA_RETRY(svga, SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
+ (uint32) condition));
+ svga->pred.query_id = queryId;
+ svga->pred.cond = condition;
}
+
+ svga->render_condition = (sq != NULL);
}
static void
-svga_set_active_query_state(struct pipe_context *pipe, boolean enable)
+svga_set_active_query_state(struct pipe_context *pipe, bool enable)
{
}
+/**
+ * \brief Toggle conditional rendering if already enabled
+ *
+ * \param svga[in] The svga context
+ * \param render_condition_enabled[in] Whether to ignore requests to turn
+ * conditional rendering off
+ * \param on[in] Whether to turn conditional rendering on or off
+ */
+void
+svga_toggle_render_condition(struct svga_context *svga,
+ boolean render_condition_enabled,
+ boolean on)
+{
+ SVGA3dQueryId query_id;
+
+ if (render_condition_enabled ||
+ svga->pred.query_id == SVGA3D_INVALID_ID) {
+ return;
+ }
+
+ /*
+ * If we get here, it means that the system supports
+ * conditional rendering since svga->pred.query_id has already been
+ * modified for this context and thus support has already been
+ * verified.
+ */
+ query_id = on ? svga->pred.query_id : SVGA3D_INVALID_ID;
+
+ SVGA_RETRY(svga, SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
+ (uint32) svga->pred.cond));
+}
+
+
void
svga_init_query_functions(struct svga_context *svga)
{