/* Count of new queries started in one stream without flushing */
unsigned queries_emitted;
/* State flags */
- unsigned state;
+ boolean flushed;
/* The buffer where query results are stored. It's used as a ring,
* data blocks for current query are stored sequentially from
* results_start to results_end, with wrapping on the buffer end */
struct list_head list;
};
-#define R600_QUERY_STATE_STARTED (1 << 0)
-#define R600_QUERY_STATE_ENDED (1 << 1)
-#define R600_QUERY_STATE_SUSPENDED (1 << 2)
-#define R600_QUERY_STATE_FLUSHED (1 << 3)
-
#define R600_CONTEXT_DRAW_PENDING (1 << 0)
#define R600_CONTEXT_DST_CACHES_DIRTY (1 << 1)
#define R600_CONTEXT_CHECK_EVENT_FLUSH (1 << 2)
u32 *pm4;
unsigned pm4_cdwords;
- struct list_head query_list;
+ /* The list of active queries. Only one query of each type can be active. */
+ struct list_head active_query_list;
+
unsigned num_query_running;
unsigned backend_mask;
unsigned max_db; /* for OQ */
memset(ctx, 0, sizeof(struct r600_context));
ctx->screen = screen;
- LIST_INITHEAD(&ctx->query_list);
+ LIST_INITHEAD(&ctx->active_query_list);
/* init dirty list */
LIST_INITHEAD(&ctx->dirty);
/* Count queries emitted without flushes, and flush if more than
* half of buffer used, to avoid overwriting results which may be
* still in use. */
- if (query->state & R600_QUERY_STATE_FLUSHED) {
+ if (query->flushed) {
query->queries_emitted = 1;
} else {
if (++query->queries_emitted > query->buffer->b.b.b.width0 / query->result_size / 2)
/* collect current results if query buffer is full */
if (new_results_end == query->results_start) {
- if (!(query->state & R600_QUERY_STATE_FLUSHED))
+ if (!query->flushed)
r600_context_flush(ctx, 0);
r600_query_result(ctx, query, TRUE);
}
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, 0);
ctx->pm4[ctx->pm4_cdwords++] = r600_context_bo_reloc(ctx, query->buffer, RADEON_USAGE_WRITE);
- query->state |= R600_QUERY_STATE_STARTED;
- query->state ^= R600_QUERY_STATE_ENDED;
ctx->num_query_running++;
}
if (query->results_end >= query->buffer->b.b.b.width0)
query->results_end = 0;
- query->state ^= R600_QUERY_STATE_STARTED;
- query->state |= R600_QUERY_STATE_ENDED;
- query->state &= ~R600_QUERY_STATE_FLUSHED;
+ query->flushed = FALSE;
ctx->num_query_running--;
}
FREE(query);
return NULL;
}
-
- LIST_ADDTAIL(&query->list, &ctx->query_list);
return query;
}
void r600_context_query_destroy(struct r600_context *ctx, struct r600_query *query)
{
pipe_resource_reference((struct pipe_resource**)&query->buffer, NULL);
- LIST_DELINIT(&query->list);
free(query);
}
{
uint64_t *result = (uint64_t*)vresult;
- if (!(query->state & R600_QUERY_STATE_FLUSHED)) {
+ if (!query->flushed) {
r600_context_flush(ctx, 0);
}
if (!r600_query_result(ctx, query, wait))
{
struct r600_query *query;
- LIST_FOR_EACH_ENTRY(query, &ctx->query_list, list) {
- if (query->state & R600_QUERY_STATE_STARTED) {
- r600_query_end(ctx, query);
- query->state |= R600_QUERY_STATE_SUSPENDED;
- }
+ LIST_FOR_EACH_ENTRY(query, &ctx->active_query_list, list) {
+ r600_query_end(ctx, query);
}
}
{
struct r600_query *query;
- LIST_FOR_EACH_ENTRY(query, &ctx->query_list, list) {
+ LIST_FOR_EACH_ENTRY(query, &ctx->active_query_list, list) {
if (flushed)
- query->state |= R600_QUERY_STATE_FLUSHED;
+ query->flushed = TRUE;
- if (query->state & R600_QUERY_STATE_SUSPENDED) {
- r600_query_begin(ctx, query);
- query->state ^= R600_QUERY_STATE_SUSPENDED;
- }
+ r600_query_begin(ctx, query);
}
}
rquery->result = 0;
rquery->results_start = rquery->results_end;
r600_query_begin(&rctx->ctx, (struct r600_query *)query);
+ LIST_ADDTAIL(&rquery->list, &rctx->ctx.active_query_list);
}
static void r600_end_query(struct pipe_context *ctx, struct pipe_query *query)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
+ struct r600_query *rquery = (struct r600_query *)query;
- r600_query_end(&rctx->ctx, (struct r600_query *)query);
+ r600_query_end(&rctx->ctx, rquery);
+ LIST_DELINIT(&rquery->list);
}
static boolean r600_get_query_result(struct pipe_context *ctx,