summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_query.c
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-02-22 00:25:55 +0100
committerMarek Olšák <[email protected]>2012-02-23 20:29:56 +0100
commitdf00dc3c817771ac5034a44dff2b14cd7759b207 (patch)
tree3527fc4b7daa84a9c87379bf89108101b845c417 /src/gallium/drivers/r600/r600_query.c
parent5b84a8c3c3f85cd6b109861c6eebe3ece29d664e (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.c38
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;