summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2015-07-31 02:39:02 +0200
committerMarek Olšák <[email protected]>2015-08-06 20:44:35 +0200
commit57245cce52d544c61f03fc966850f0f94e8118d5 (patch)
treee374d64930bf7d43517fb1673f677cb1e4360d79 /src/gallium/drivers
parentb2eb13d602f71f19216284a584834cdaa2550eb3 (diff)
gallium/radeon: suspend timer queries between IBs
When we are measuring the time spent in a draw call, an unexpected flush can distort the result. Reviewed-by: Michel Dänzer <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r600/r600_hw_context.c3
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.c8
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.h9
-rw-r--r--src/gallium/drivers/radeon/r600_query.c68
-rw-r--r--src/gallium/drivers/radeonsi/si_hw_context.c3
5 files changed, 66 insertions, 25 deletions
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index 8eb0c6806b9..9155707f866 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -68,7 +68,8 @@ void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
}
/* Count in queries_suspend. */
- num_dw += ctx->b.num_cs_dw_nontimer_queries_suspend;
+ num_dw += ctx->b.num_cs_dw_nontimer_queries_suspend +
+ ctx->b.num_cs_dw_timer_queries_suspend;
/* Count in streamout_end at the end of CS. */
if (ctx->b.streamout.begin_emitted) {
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index 75e820144e3..c940f6d35c2 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -132,10 +132,11 @@ void r600_preflush_suspend_features(struct r600_common_context *ctx)
}
/* suspend queries */
- ctx->nontimer_queries_suspended = false;
+ ctx->queries_suspended_for_flush = false;
if (ctx->num_cs_dw_nontimer_queries_suspend) {
r600_suspend_nontimer_queries(ctx);
- ctx->nontimer_queries_suspended = true;
+ r600_suspend_timer_queries(ctx);
+ ctx->queries_suspended_for_flush = true;
}
ctx->streamout.suspended = false;
@@ -153,8 +154,9 @@ void r600_postflush_resume_features(struct r600_common_context *ctx)
}
/* resume queries */
- if (ctx->nontimer_queries_suspended) {
+ if (ctx->queries_suspended_for_flush) {
r600_resume_nontimer_queries(ctx);
+ r600_resume_timer_queries(ctx);
}
/* Re-enable render condition. */
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index e2a60c59c82..fbd2a21da17 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -384,11 +384,14 @@ struct r600_common_context {
int num_occlusion_queries;
/* Keep track of non-timer queries, because they should be suspended
* during context flushing.
- * The timer queries (TIME_ELAPSED) shouldn't be suspended. */
+ * The timer queries (TIME_ELAPSED) shouldn't be suspended for blits,
+ * but they should be suspended between IBs. */
struct list_head active_nontimer_queries;
+ struct list_head active_timer_queries;
unsigned num_cs_dw_nontimer_queries_suspend;
+ unsigned num_cs_dw_timer_queries_suspend;
/* If queries have been suspended. */
- bool nontimer_queries_suspended;
+ bool queries_suspended_for_flush;
/* Additional hardware info. */
unsigned backend_mask;
unsigned max_db; /* for OQ */
@@ -503,6 +506,8 @@ unsigned r600_gpu_load_end(struct r600_common_screen *rscreen, uint64_t begin);
void r600_query_init(struct r600_common_context *rctx);
void r600_suspend_nontimer_queries(struct r600_common_context *ctx);
void r600_resume_nontimer_queries(struct r600_common_context *ctx);
+void r600_suspend_timer_queries(struct r600_common_context *ctx);
+void r600_resume_timer_queries(struct r600_common_context *ctx);
void r600_query_init_backend_mask(struct r600_common_context *ctx);
/* r600_streamout.c */
diff --git a/src/gallium/drivers/radeon/r600_query.c b/src/gallium/drivers/radeon/r600_query.c
index 909d5029bfa..7fc22537f43 100644
--- a/src/gallium/drivers/radeon/r600_query.c
+++ b/src/gallium/drivers/radeon/r600_query.c
@@ -226,9 +226,10 @@ static void r600_emit_query_begin(struct r600_common_context *ctx, struct r600_q
r600_emit_reloc(ctx, &ctx->rings.gfx, query->buffer.buf, RADEON_USAGE_WRITE,
RADEON_PRIO_MIN);
- if (!r600_is_timer_query(query->type)) {
+ if (r600_is_timer_query(query->type))
+ ctx->num_cs_dw_timer_queries_suspend += query->num_cs_dw;
+ else
ctx->num_cs_dw_nontimer_queries_suspend += query->num_cs_dw;
- }
}
static void r600_emit_query_end(struct r600_common_context *ctx, struct r600_query *query)
@@ -290,9 +291,10 @@ static void r600_emit_query_end(struct r600_common_context *ctx, struct r600_que
query->buffer.results_end += query->result_size;
if (r600_query_needs_begin(query->type)) {
- if (!r600_is_timer_query(query->type)) {
+ if (r600_is_timer_query(query->type))
+ ctx->num_cs_dw_timer_queries_suspend -= query->num_cs_dw;
+ else
ctx->num_cs_dw_nontimer_queries_suspend -= query->num_cs_dw;
- }
}
r600_update_occlusion_query_state(ctx, query->type, -1);
@@ -503,9 +505,10 @@ static boolean r600_begin_query(struct pipe_context *ctx,
r600_emit_query_begin(rctx, rquery);
- if (!r600_is_timer_query(rquery->type)) {
+ if (r600_is_timer_query(rquery->type))
+ LIST_ADDTAIL(&rquery->list, &rctx->active_timer_queries);
+ else
LIST_ADDTAIL(&rquery->list, &rctx->active_nontimer_queries);
- }
return true;
}
@@ -561,9 +564,8 @@ static void r600_end_query(struct pipe_context *ctx, struct pipe_query *query)
r600_emit_query_end(rctx, rquery);
- if (r600_query_needs_begin(rquery->type) && !r600_is_timer_query(rquery->type)) {
+ if (r600_query_needs_begin(rquery->type))
LIST_DELINIT(&rquery->list);
- }
}
static unsigned r600_query_read_result(char *map, unsigned start_index, unsigned end_index,
@@ -838,22 +840,37 @@ static void r600_render_condition(struct pipe_context *ctx,
}
}
-void r600_suspend_nontimer_queries(struct r600_common_context *ctx)
+static void r600_suspend_queries(struct r600_common_context *ctx,
+ struct list_head *query_list,
+ unsigned *num_cs_dw_queries_suspend)
{
struct r600_query *query;
- LIST_FOR_EACH_ENTRY(query, &ctx->active_nontimer_queries, list) {
+ LIST_FOR_EACH_ENTRY(query, query_list, list) {
r600_emit_query_end(ctx, query);
}
- assert(ctx->num_cs_dw_nontimer_queries_suspend == 0);
+ assert(*num_cs_dw_queries_suspend == 0);
+}
+
+void r600_suspend_nontimer_queries(struct r600_common_context *ctx)
+{
+ r600_suspend_queries(ctx, &ctx->active_nontimer_queries,
+ &ctx->num_cs_dw_nontimer_queries_suspend);
}
-static unsigned r600_queries_num_cs_dw_for_resuming(struct r600_common_context *ctx)
+void r600_suspend_timer_queries(struct r600_common_context *ctx)
+{
+ r600_suspend_queries(ctx, &ctx->active_timer_queries,
+ &ctx->num_cs_dw_timer_queries_suspend);
+}
+
+static unsigned r600_queries_num_cs_dw_for_resuming(struct r600_common_context *ctx,
+ struct list_head *query_list)
{
struct r600_query *query;
unsigned num_dw = 0;
- LIST_FOR_EACH_ENTRY(query, &ctx->active_nontimer_queries, list) {
+ LIST_FOR_EACH_ENTRY(query, query_list, list) {
/* begin + end */
num_dw += query->num_cs_dw * 2;
@@ -872,21 +889,35 @@ static unsigned r600_queries_num_cs_dw_for_resuming(struct r600_common_context *
return num_dw;
}
-void r600_resume_nontimer_queries(struct r600_common_context *ctx)
+static void r600_resume_queries(struct r600_common_context *ctx,
+ struct list_head *query_list,
+ unsigned *num_cs_dw_queries_suspend)
{
struct r600_query *query;
+ unsigned num_cs_dw = r600_queries_num_cs_dw_for_resuming(ctx, query_list);
- assert(ctx->num_cs_dw_nontimer_queries_suspend == 0);
+ assert(*num_cs_dw_queries_suspend == 0);
/* Check CS space here. Resuming must not be interrupted by flushes. */
- ctx->need_gfx_cs_space(&ctx->b,
- r600_queries_num_cs_dw_for_resuming(ctx), TRUE);
+ ctx->need_gfx_cs_space(&ctx->b, num_cs_dw, TRUE);
- LIST_FOR_EACH_ENTRY(query, &ctx->active_nontimer_queries, list) {
+ LIST_FOR_EACH_ENTRY(query, query_list, list) {
r600_emit_query_begin(ctx, query);
}
}
+void r600_resume_nontimer_queries(struct r600_common_context *ctx)
+{
+ r600_resume_queries(ctx, &ctx->active_nontimer_queries,
+ &ctx->num_cs_dw_nontimer_queries_suspend);
+}
+
+void r600_resume_timer_queries(struct r600_common_context *ctx)
+{
+ r600_resume_queries(ctx, &ctx->active_timer_queries,
+ &ctx->num_cs_dw_timer_queries_suspend);
+}
+
/* Get backends mask */
void r600_query_init_backend_mask(struct r600_common_context *ctx)
{
@@ -979,4 +1010,5 @@ void r600_query_init(struct r600_common_context *rctx)
rctx->b.render_condition = r600_render_condition;
LIST_INITHEAD(&rctx->active_nontimer_queries);
+ LIST_INITHEAD(&rctx->active_timer_queries);
}
diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c
index 581b130caec..b80245c9785 100644
--- a/src/gallium/drivers/radeonsi/si_hw_context.c
+++ b/src/gallium/drivers/radeonsi/si_hw_context.c
@@ -63,7 +63,8 @@ void si_need_cs_space(struct si_context *ctx, unsigned num_dw,
}
/* Count in queries_suspend. */
- num_dw += ctx->b.num_cs_dw_nontimer_queries_suspend;
+ num_dw += ctx->b.num_cs_dw_nontimer_queries_suspend +
+ ctx->b.num_cs_dw_timer_queries_suspend;
/* Count in streamout_end at the end of CS. */
if (ctx->b.streamout.begin_emitted) {