intel/perf: move delete_query to gen_perf
[mesa.git] / src / mesa / drivers / dri / i965 / brw_performance_query.c
index addb989f47b0830c5f26b8e5ec3e562827a39156..45298e79112bcf480261214e3c243d34328e38bd 100644 (file)
@@ -311,119 +311,6 @@ enum OaReadStatus {
    OA_READ_STATUS_FINISHED,
 };
 
-static enum OaReadStatus
-read_oa_samples_until(struct brw_context *brw,
-                      uint32_t start_timestamp,
-                      uint32_t end_timestamp)
-{
-   struct gen_perf_context *perf_ctx = &brw->perf_ctx;
-   struct exec_node *tail_node =
-      exec_list_get_tail(&perf_ctx->sample_buffers);
-   struct oa_sample_buf *tail_buf =
-      exec_node_data(struct oa_sample_buf, tail_node, link);
-   uint32_t last_timestamp = tail_buf->last_timestamp;
-
-   while (1) {
-      struct oa_sample_buf *buf = gen_perf_get_free_sample_buf(perf_ctx);
-      uint32_t offset;
-      int len;
-
-      while ((len = read(perf_ctx->oa_stream_fd, buf->buf,
-                         sizeof(buf->buf))) < 0 && errno == EINTR)
-         ;
-
-      if (len <= 0) {
-         exec_list_push_tail(&perf_ctx->free_sample_buffers, &buf->link);
-
-         if (len < 0) {
-            if (errno == EAGAIN)
-               return ((last_timestamp - start_timestamp) >=
-                       (end_timestamp - start_timestamp)) ?
-                      OA_READ_STATUS_FINISHED :
-                      OA_READ_STATUS_UNFINISHED;
-            else {
-               DBG("Error reading i915 perf samples: %m\n");
-            }
-         } else
-            DBG("Spurious EOF reading i915 perf samples\n");
-
-         return OA_READ_STATUS_ERROR;
-      }
-
-      buf->len = len;
-      exec_list_push_tail(&perf_ctx->sample_buffers, &buf->link);
-
-      /* Go through the reports and update the last timestamp. */
-      offset = 0;
-      while (offset < buf->len) {
-         const struct drm_i915_perf_record_header *header =
-            (const struct drm_i915_perf_record_header *) &buf->buf[offset];
-         uint32_t *report = (uint32_t *) (header + 1);
-
-         if (header->type == DRM_I915_PERF_RECORD_SAMPLE)
-            last_timestamp = report[1];
-
-         offset += header->size;
-      }
-
-      buf->last_timestamp = last_timestamp;
-   }
-
-   unreachable("not reached");
-   return OA_READ_STATUS_ERROR;
-}
-
-/**
- * Try to read all the reports until either the delimiting timestamp
- * or an error arises.
- */
-static bool
-read_oa_samples_for_query(struct brw_context *brw,
-                          struct gen_perf_query_object *obj)
-{
-   uint32_t *start;
-   uint32_t *last;
-   uint32_t *end;
-
-   struct gen_perf_config *perf_cfg = brw->perf_ctx.perf;
-
-   /* We need the MI_REPORT_PERF_COUNT to land before we can start
-    * accumulate. */
-   assert(!perf_cfg->vtbl.batch_references(&brw->batch, obj->oa.bo) &&
-          !brw_bo_busy(obj->oa.bo));
-
-   /* Map the BO once here and let accumulate_oa_reports() unmap
-    * it. */
-   if (obj->oa.map == NULL)
-      obj->oa.map = perf_cfg->vtbl.bo_map(brw, obj->oa.bo, MAP_READ);
-
-   start = last = obj->oa.map;
-   end = obj->oa.map + MI_RPC_BO_END_OFFSET_BYTES;
-
-   if (start[0] != obj->oa.begin_report_id) {
-      DBG("Spurious start report id=%"PRIu32"\n", start[0]);
-      return true;
-   }
-   if (end[0] != (obj->oa.begin_report_id + 1)) {
-      DBG("Spurious end report id=%"PRIu32"\n", end[0]);
-      return true;
-   }
-
-   /* Read the reports until the end timestamp. */
-   switch (read_oa_samples_until(brw, start[1], end[1])) {
-   case OA_READ_STATUS_ERROR:
-      /* Fallthrough and let accumulate_oa_reports() deal with the
-       * error. */
-   case OA_READ_STATUS_FINISHED:
-      return true;
-   case OA_READ_STATUS_UNFINISHED:
-      return false;
-   }
-
-   unreachable("invalid read status");
-   return false;
-}
-
 /**
  * Accumulate raw OA counter values based on deltas between pairs of
  * OA reports.
@@ -667,47 +554,10 @@ brw_wait_perf_query(struct gl_context *ctx, struct gl_perf_query_object *o)
    struct brw_context *brw = brw_context(ctx);
    struct brw_perf_query_object *brw_query = brw_perf_query(o);
    struct gen_perf_query_object *obj = brw_query->query;
-   struct brw_bo *bo = NULL;
-   struct gen_perf_config *perf_cfg = brw->perf_ctx.perf;
 
    assert(!o->Ready);
 
-   switch (obj->queryinfo->kind) {
-   case GEN_PERF_QUERY_TYPE_OA:
-   case GEN_PERF_QUERY_TYPE_RAW:
-      bo = obj->oa.bo;
-      break;
-
-   case GEN_PERF_QUERY_TYPE_PIPELINE:
-      bo = obj->pipeline_stats.bo;
-      break;
-
-   default:
-      unreachable("Unknown query type");
-      break;
-   }
-
-   if (bo == NULL)
-      return;
-
-   /* If the current batch references our results bo then we need to
-    * flush first...
-    */
-   if (perf_cfg->vtbl.batch_references(&brw->batch, bo))
-      perf_cfg->vtbl.batchbuffer_flush(brw, __FILE__, __LINE__);
-
-   perf_cfg->vtbl.bo_wait_rendering(bo);
-
-   /* Due to a race condition between the OA unit signaling report
-    * availability and the report actually being written into memory,
-    * we need to wait for all the reports to come in before we can
-    * read them.
-    */
-   if (obj->queryinfo->kind == GEN_PERF_QUERY_TYPE_OA ||
-       obj->queryinfo->kind == GEN_PERF_QUERY_TYPE_RAW) {
-      while (!read_oa_samples_for_query(brw, obj))
-         ;
-   }
+   gen_perf_wait_query(&brw->perf_ctx, obj, &brw->batch);
 }
 
 static bool
@@ -717,30 +567,11 @@ brw_is_perf_query_ready(struct gl_context *ctx,
    struct brw_context *brw = brw_context(ctx);
    struct brw_perf_query_object *brw_query = brw_perf_query(o);
    struct gen_perf_query_object *obj = brw_query->query;
-   struct gen_perf_config *perf_cfg = brw->perf_ctx.perf;
 
    if (o->Ready)
       return true;
 
-   switch (obj->queryinfo->kind) {
-   case GEN_PERF_QUERY_TYPE_OA:
-   case GEN_PERF_QUERY_TYPE_RAW:
-      return (obj->oa.results_accumulated ||
-              (obj->oa.bo &&
-               !perf_cfg->vtbl.batch_references(&brw->batch, obj->oa.bo) &&
-               !brw_bo_busy(obj->oa.bo) &&
-               read_oa_samples_for_query(brw, obj)));
-   case GEN_PERF_QUERY_TYPE_PIPELINE:
-      return (obj->pipeline_stats.bo &&
-              !perf_cfg->vtbl.batch_references(&brw->batch, obj->pipeline_stats.bo) &&
-              !brw_bo_busy(obj->pipeline_stats.bo));
-
-   default:
-      unreachable("Unknown query type");
-      break;
-   }
-
-   return false;
+   return gen_perf_is_query_ready(&brw->perf_ctx, obj, &brw->batch);
 }
 
 static void
@@ -956,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;
@@ -970,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);
 }
 
@@ -1178,7 +971,7 @@ typedef void (*store_register_mem64_t)(void *ctx, void *bo,
                                        uint32_t reg, uint32_t offset);
 typedef bool (*batch_references_t)(void *batch, void *bo);
 typedef void (*bo_wait_rendering_t)(void *bo);
-
+typedef int (*bo_busy_t)(void *bo);
 
 static unsigned
 brw_init_perf_query_info(struct gl_context *ctx)
@@ -1207,6 +1000,7 @@ brw_init_perf_query_info(struct gl_context *ctx)
       (store_register_mem64_t) brw_store_register_mem64;
    perf_cfg->vtbl.batch_references = (batch_references_t)brw_batch_references;
    perf_cfg->vtbl.bo_wait_rendering = (bo_wait_rendering_t)brw_bo_wait_rendering;
+   perf_cfg->vtbl.bo_busy = (bo_busy_t)brw_bo_busy;
 
    gen_perf_init_context(perf_ctx, perf_cfg, brw, brw->bufmgr, devinfo,
                          brw->hw_ctx, brw->screen->driScrnPriv->fd);