diff options
author | Marek Olšák <[email protected]> | 2012-02-22 00:25:55 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-02-23 20:29:56 +0100 |
commit | df00dc3c817771ac5034a44dff2b14cd7759b207 (patch) | |
tree | 3527fc4b7daa84a9c87379bf89108101b845c417 /src/gallium/drivers/r600/r600_query.c | |
parent | 5b84a8c3c3f85cd6b109861c6eebe3ece29d664e (diff) |
r600g: rework queries
We always mapped the query buffer in begin_query, causing stalls
if the buffer was busy.
This commit reworks it such that the query buffer is only mapped
in get_query_result as it's supposed to be.
The query buffer is no longer treated as a ring buffer. Instead, the results
are just appended and when the buffer is full, we create a new one. One query
can have more than one query buffer, though that's a very rare case.
Begin_query releases all query buffers.
Reviewed-by: Jerome Glisse <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/r600_query.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_query.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c index f2e6d010659..cf026abf1fb 100644 --- a/src/gallium/drivers/r600/r600_query.c +++ b/src/gallium/drivers/r600/r600_query.c @@ -22,6 +22,7 @@ */ #include "r600_pipe.h" #include "r600d.h" +#include "util/u_memory.h" static struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned query_type) { @@ -56,6 +57,30 @@ static void r600_update_occlusion_query_state(struct r600_context *rctx, } } +static void r600_query_discard_results(struct r600_context *rctx, + struct r600_query *query) +{ + /* Discard the old query buffers. */ + struct r600_query_buffer *prev = query->buffer.previous; + + while (prev) { + struct r600_query_buffer *qbuf = prev; + prev = prev->previous; + pipe_resource_reference((struct pipe_resource**)&qbuf->buf, NULL); + FREE(qbuf); + } + + /* Obtain a new buffer if the current one can't be mapped without a stall. */ + if (rctx->ws->cs_is_buffer_referenced(rctx->cs, query->buffer.buf->cs_buf) || + rctx->ws->buffer_is_busy(query->buffer.buf->buf, RADEON_USAGE_READWRITE)) { + pipe_resource_reference((struct pipe_resource**)&query->buffer.buf, NULL); + query->buffer.buf = r600_new_query_buffer(rctx, query->type); + } + + query->buffer.results_end = 0; + query->buffer.previous = NULL; +} + static void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query) { struct r600_context *rctx = (struct r600_context *)ctx; @@ -63,9 +88,8 @@ static void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query) r600_update_occlusion_query_state(rctx, rquery->type, 1); - memset(&rquery->result, 0, sizeof(rquery->result)); - rquery->results_start = rquery->results_end; - r600_query_begin(rctx, (struct r600_query *)query); + r600_query_discard_results(rctx, rquery); + r600_query_begin(rctx, rquery); LIST_ADDTAIL(&rquery->list, &rctx->active_query_list); } @@ -98,14 +122,6 @@ static void r600_render_condition(struct pipe_context *ctx, struct r600_query *rquery = (struct r600_query *)query; int wait_flag = 0; - /* If we already have nonzero result, render unconditionally */ - if (query != NULL && rquery->result.u64 != 0) { - if (rctx->current_render_cond) { - r600_render_condition(ctx, NULL, 0); - } - return; - } - rctx->current_render_cond = query; rctx->current_render_cond_mode = mode; |