diff options
-rw-r--r-- | src/intel/perf/gen_perf.c | 91 | ||||
-rw-r--r-- | src/intel/perf/gen_perf.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_performance_query.c | 40 |
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); } |