intel/perf: move client reference counts into perf
[mesa.git] / src / intel / perf / gen_perf.c
index 9df94512dc683f6bad0c45b6a7250c91e8bef782..4adcd464f1927f648e69f1aad1b7b82e13ff09a7 100644 (file)
@@ -867,3 +867,124 @@ gen_perf_reap_old_sample_buffers(struct gen_perf_context *perf_ctx)
          return;
    }
 }
+
+void
+gen_perf_free_sample_bufs(struct gen_perf_context *perf_ctx)
+{
+   foreach_list_typed_safe(struct oa_sample_buf, buf, link,
+                           &perf_ctx->free_sample_buffers)
+      ralloc_free(buf);
+
+   exec_list_make_empty(&perf_ctx->free_sample_buffers);
+}
+
+/******************************************************************************/
+
+/**
+ * Emit MI_STORE_REGISTER_MEM commands to capture all of the
+ * pipeline statistics for the performance query object.
+ */
+void
+gen_perf_snapshot_statistics_registers(void *context,
+                                       struct gen_perf_config *perf,
+                                       struct gen_perf_query_object *obj,
+                                       uint32_t offset_in_bytes)
+{
+   const struct gen_perf_query_info *query = obj->queryinfo;
+   const int n_counters = query->n_counters;
+
+   for (int i = 0; i < n_counters; i++) {
+      const struct gen_perf_query_counter *counter = &query->counters[i];
+
+      assert(counter->data_type == GEN_PERF_COUNTER_DATA_TYPE_UINT64);
+
+      perf->vtbl.store_register_mem64(context, obj->pipeline_stats.bo,
+                                      counter->pipeline_stat.reg,
+                                      offset_in_bytes + i * sizeof(uint64_t));
+   }
+}
+
+void
+gen_perf_close(struct gen_perf_context *perfquery,
+               const struct gen_perf_query_info *query)
+{
+   if (perfquery->oa_stream_fd != -1) {
+      close(perfquery->oa_stream_fd);
+      perfquery->oa_stream_fd = -1;
+   }
+   if (query->kind == GEN_PERF_QUERY_TYPE_RAW) {
+      struct gen_perf_query_info *raw_query =
+         (struct gen_perf_query_info *) query;
+      raw_query->oa_metrics_set_id = 0;
+   }
+}
+
+bool
+gen_perf_open(struct gen_perf_context *perf_ctx,
+              int metrics_set_id,
+              int report_format,
+              int period_exponent,
+              int drm_fd,
+              uint32_t ctx_id)
+{
+   uint64_t properties[] = {
+      /* Single context sampling */
+      DRM_I915_PERF_PROP_CTX_HANDLE, ctx_id,
+
+      /* Include OA reports in samples */
+      DRM_I915_PERF_PROP_SAMPLE_OA, true,
+
+      /* OA unit configuration */
+      DRM_I915_PERF_PROP_OA_METRICS_SET, metrics_set_id,
+      DRM_I915_PERF_PROP_OA_FORMAT, report_format,
+      DRM_I915_PERF_PROP_OA_EXPONENT, period_exponent,
+   };
+   struct drm_i915_perf_open_param param = {
+      .flags = I915_PERF_FLAG_FD_CLOEXEC |
+               I915_PERF_FLAG_FD_NONBLOCK |
+               I915_PERF_FLAG_DISABLED,
+      .num_properties = ARRAY_SIZE(properties) / 2,
+      .properties_ptr = (uintptr_t) properties,
+   };
+   int fd = gen_ioctl(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param);
+   if (fd == -1) {
+      DBG("Error opening gen perf OA stream: %m\n");
+      return false;
+   }
+
+   perf_ctx->oa_stream_fd = fd;
+
+   perf_ctx->current_oa_metrics_set_id = metrics_set_id;
+   perf_ctx->current_oa_format = report_format;
+
+   return true;
+}
+
+bool
+gen_perf_inc_n_users(struct gen_perf_context *perf_ctx)
+{
+   if (perf_ctx->n_oa_users == 0 &&
+       gen_ioctl(perf_ctx->oa_stream_fd, I915_PERF_IOCTL_ENABLE, 0) < 0)
+   {
+      return false;
+   }
+   ++perf_ctx->n_oa_users;
+
+   return true;
+}
+
+void
+gen_perf_dec_n_users(struct gen_perf_context *perf_ctx)
+{
+   /* Disabling the i915 perf stream will effectively disable the OA
+    * counters.  Note it's important to be sure there are no outstanding
+    * MI_RPC commands at this point since they could stall the CS
+    * indefinitely once OACONTROL is disabled.
+    */
+   --perf_ctx->n_oa_users;
+   if (perf_ctx->n_oa_users == 0 &&
+       gen_ioctl(perf_ctx->oa_stream_fd, I915_PERF_IOCTL_DISABLE, 0) < 0)
+   {
+      DBG("WARNING: Error disabling gen perf stream: %m\n");
+   }
+}