summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/intel/perf/gen_perf.c91
-rw-r--r--src/intel/perf/gen_perf.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_performance_query.c40
3 files changed, 94 insertions, 39 deletions
diff --git a/src/intel/perf/gen_perf.c b/src/intel/perf/gen_perf.c
index fe5bbabe3c8..fa5a53ff3d4 100644
--- a/src/intel/perf/gen_perf.c
+++ b/src/intel/perf/gen_perf.c
@@ -1529,3 +1529,94 @@ gen_perf_is_query_ready(struct gen_perf_context *perf_ctx,
return false;
}
+
+/**
+ * Remove a query from the global list of unaccumulated queries once
+ * after successfully accumulating the OA reports associated with the
+ * query in accumulate_oa_reports() or when discarding unwanted query
+ * results.
+ */
+static void
+drop_from_unaccumulated_query_list(struct gen_perf_context *perf_ctx,
+ struct gen_perf_query_object *query)
+{
+ for (int i = 0; i < perf_ctx->unaccumulated_elements; i++) {
+ if (perf_ctx->unaccumulated[i] == query) {
+ int last_elt = --perf_ctx->unaccumulated_elements;
+
+ if (i == last_elt)
+ perf_ctx->unaccumulated[i] = NULL;
+ else {
+ perf_ctx->unaccumulated[i] =
+ perf_ctx->unaccumulated[last_elt];
+ }
+
+ break;
+ }
+ }
+
+ /* Drop our samples_head reference so that associated periodic
+ * sample data buffers can potentially be reaped if they aren't
+ * referenced by any other queries...
+ */
+
+ struct oa_sample_buf *buf =
+ exec_node_data(struct oa_sample_buf, query->oa.samples_head, link);
+
+ assert(buf->refcount > 0);
+ buf->refcount--;
+
+ query->oa.samples_head = NULL;
+
+ gen_perf_reap_old_sample_buffers(perf_ctx);
+}
+
+void
+gen_perf_delete_query(struct gen_perf_context *perf_ctx,
+ struct gen_perf_query_object *query)
+{
+ struct gen_perf_config *perf_cfg = perf_ctx->perf;
+
+ /* We can assume that the frontend waits for a query to complete
+ * before ever calling into here, so we don't have to worry about
+ * deleting an in-flight query object.
+ */
+ switch (query->queryinfo->kind) {
+ case GEN_PERF_QUERY_TYPE_OA:
+ case GEN_PERF_QUERY_TYPE_RAW:
+ if (query->oa.bo) {
+ if (!query->oa.results_accumulated) {
+ drop_from_unaccumulated_query_list(perf_ctx, query);
+ gen_perf_dec_n_users(perf_ctx);
+ }
+
+ perf_cfg->vtbl.bo_unreference(query->oa.bo);
+ query->oa.bo = NULL;
+ }
+
+ query->oa.results_accumulated = false;
+ break;
+
+ case GEN_PERF_QUERY_TYPE_PIPELINE:
+ if (query->pipeline_stats.bo) {
+ perf_cfg->vtbl.bo_unreference(query->pipeline_stats.bo);
+ query->pipeline_stats.bo = NULL;
+ }
+ break;
+
+ default:
+ unreachable("Unknown query type");
+ break;
+ }
+
+ /* As an indication that the INTEL_performance_query extension is no
+ * longer in use, it's a good time to free our cache of sample
+ * buffers and close any current i915-perf stream.
+ */
+ if (--perf_ctx->n_query_instances == 0) {
+ gen_perf_free_sample_bufs(perf_ctx);
+ gen_perf_close(perf_ctx, query->queryinfo);
+ }
+
+ free(query);
+}
diff --git a/src/intel/perf/gen_perf.h b/src/intel/perf/gen_perf.h
index efb884afe36..9dae8770aac 100644
--- a/src/intel/perf/gen_perf.h
+++ b/src/intel/perf/gen_perf.h
@@ -630,5 +630,7 @@ void gen_perf_wait_query(struct gen_perf_context *perf_ctx,
bool gen_perf_is_query_ready(struct gen_perf_context *perf_ctx,
struct gen_perf_query_object *query,
void *current_batch);
+void gen_perf_delete_query(struct gen_perf_context *perf_ctx,
+ struct gen_perf_query_object *query);
#endif /* GEN_PERF_H */
diff --git a/src/mesa/drivers/dri/i965/brw_performance_query.c b/src/mesa/drivers/dri/i965/brw_performance_query.c
index 4bc652007a1..45298e79112 100644
--- a/src/mesa/drivers/dri/i965/brw_performance_query.c
+++ b/src/mesa/drivers/dri/i965/brw_performance_query.c
@@ -787,7 +787,6 @@ brw_delete_perf_query(struct gl_context *ctx,
struct gl_perf_query_object *o)
{
struct brw_context *brw = brw_context(ctx);
- struct gen_perf_config *perf_cfg = brw->perf_ctx.perf;
struct brw_perf_query_object *brw_query = brw_perf_query(o);
struct gen_perf_query_object *obj = brw_query->query;
struct gen_perf_context *perf_ctx = &brw->perf_ctx;
@@ -801,44 +800,7 @@ brw_delete_perf_query(struct gl_context *ctx,
DBG("Delete(%d)\n", o->Id);
- switch (obj->queryinfo->kind) {
- case GEN_PERF_QUERY_TYPE_OA:
- case GEN_PERF_QUERY_TYPE_RAW:
- if (obj->oa.bo) {
- if (!obj->oa.results_accumulated) {
- drop_from_unaccumulated_query_list(brw, obj);
- gen_perf_dec_n_users(perf_ctx);
- }
-
- perf_cfg->vtbl.bo_unreference(obj->oa.bo);
- obj->oa.bo = NULL;
- }
-
- obj->oa.results_accumulated = false;
- break;
-
- case GEN_PERF_QUERY_TYPE_PIPELINE:
- if (obj->pipeline_stats.bo) {
- perf_cfg->vtbl.bo_unreference(obj->pipeline_stats.bo);
- obj->pipeline_stats.bo = NULL;
- }
- break;
-
- default:
- unreachable("Unknown query type");
- break;
- }
-
- /* As an indication that the INTEL_performance_query extension is no
- * longer in use, it's a good time to free our cache of sample
- * buffers and close any current i915-perf stream.
- */
- if (--perf_ctx->n_query_instances == 0) {
- gen_perf_free_sample_bufs(perf_ctx);
- gen_perf_close(perf_ctx, obj->queryinfo);
- }
-
- free(obj);
+ gen_perf_delete_query(perf_ctx, obj);
free(brw_query);
}