i965: Start and stop OA counters as necessary.
authorKenneth Graunke <kenneth@whitecape.org>
Sun, 3 Nov 2013 03:58:10 +0000 (20:58 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Nov 2013 23:01:14 +0000 (15:01 -0800)
We need to start OA at the beginning of each batch where monitors are
active.  OACONTROL isn't part of the hardware context, so to avoid
leaving counters enabled for other applications, we turn them off at the
end of the batch too.

We also need to start them at BeginPerfMonitor time (unless they've
already been started).  We stop them when the monitor last ends as well.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_performance_monitor.c
src/mesa/drivers/dri/i965/intel_batchbuffer.c
src/mesa/drivers/dri/i965/intel_batchbuffer.h

index cb92b282324b328a2017114f176afa4d6f8b00e2..896f5c394f564ac8e628fac505a607058cd55d5d 100644 (file)
@@ -1633,6 +1633,8 @@ bool brw_render_target_supported(struct brw_context *brw,
 /* brw_performance_monitor.c */
 void brw_init_performance_monitors(struct brw_context *brw);
 void brw_dump_perf_monitors(struct brw_context *brw);
+void brw_perf_monitor_new_batch(struct brw_context *brw);
+void brw_perf_monitor_finish_batch(struct brw_context *brw);
 
 /* intel_extensions.c */
 extern void intelInitExtensions(struct gl_context *ctx);
index 85c395b3aed511e576e6d9006eae4ce9a6817571..707deb24a9e7c3c58615bffddc2a4f011af3f598 100644 (file)
@@ -766,6 +766,14 @@ brw_begin_perf_monitor(struct gl_context *ctx,
       drm_intel_bo_unmap(monitor->oa_bo);
 #endif
 
+      /* If the OA counters aren't already on, enable them. */
+      if (brw->perfmon.oa_users == 0) {
+         /* Ensure the OACONTROL enable and snapshot land in the same batch. */
+         int space = (MI_REPORT_PERF_COUNT_BATCH_DWORDS + 3) * 4;
+         intel_batchbuffer_require_space(brw, space, RENDER_RING);
+         start_oa_counters(brw);
+      }
+
       /* Take a starting OA counter snapshot. */
       emit_mi_report_perf_count(brw, monitor->oa_bo, 0, REPORT_ID);
 
@@ -801,6 +809,9 @@ brw_end_perf_monitor(struct gl_context *ctx,
                                 SECOND_SNAPSHOT_OFFSET_IN_BYTES, REPORT_ID);
 
       --brw->perfmon.oa_users;
+
+      if (brw->perfmon.oa_users == 0)
+         stop_oa_counters(brw);
    }
 
    if (monitor_needs_statistics_registers(brw, m)) {
@@ -925,6 +936,45 @@ brw_delete_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m
 
 /******************************************************************************/
 
+/**
+ * Called at the start of every render ring batch.
+ *
+ * Enable the OA counters if required.
+ */
+void
+brw_perf_monitor_new_batch(struct brw_context *brw)
+{
+   assert(brw->batch.ring == RENDER_RING);
+   assert(brw->gen < 6 || brw->batch.used == 0);
+
+   if (brw->perfmon.oa_users == 0)
+      return;
+
+   if (brw->gen >= 6)
+      start_oa_counters(brw);
+}
+
+/**
+ * Called at the end of every render ring batch.
+ *
+ * Disable the OA counters.
+ *
+ * This relies on there being enough space in BATCH_RESERVED.
+ */
+void
+brw_perf_monitor_finish_batch(struct brw_context *brw)
+{
+   assert(brw->batch.ring == RENDER_RING);
+
+   if (brw->perfmon.oa_users == 0)
+      return;
+
+   if (brw->gen >= 6)
+      stop_oa_counters(brw);
+}
+
+/******************************************************************************/
+
 void
 brw_init_performance_monitors(struct brw_context *brw)
 {
index f66c2dd193a21bfa6d1960db21377a7927ce1ccc..99608dce9af8a72a64d44586da1fdebadc899686 100644 (file)
@@ -187,6 +187,9 @@ intel_batchbuffer_emit_render_ring_prelude(struct brw_context *brw)
     * what that batch contributed.  Emit state packets to write them to a BO.
     */
    brw_emit_query_begin(brw);
+
+   /* We may also need to enable OA counters. */
+   brw_perf_monitor_new_batch(brw);
 }
 
 /**
@@ -247,6 +250,10 @@ brw_finish_batch(struct brw_context *brw)
     */
    brw_emit_query_end(brw);
 
+   /* We may also need to disable OA counters. */
+   if (brw->batch.ring == RENDER_RING)
+      brw_perf_monitor_finish_batch(brw);
+
    if (brw->curbe.curbe_bo) {
       drm_intel_gem_bo_unmap_gtt(brw->curbe.curbe_bo);
       drm_intel_bo_unreference(brw->curbe.curbe_bo);
index 861aed418bf0553d21227310dec5be20991e468f..3b43ccfba13c578949b8763cad6ea7631061852e 100644 (file)
@@ -19,8 +19,9 @@ extern "C" {
  * - Optional MI_NOOP for ensuring the batch length is qword aligned (4 bytes)
  * - Any state emitted by vtbl->finish_batch():
  *   - Gen4-5 record ending occlusion query values (4 * 4 = 16 bytes)
+ *   - Disabling OA counters on Gen6+ (3 DWords = 12 bytes)
  */
-#define BATCH_RESERVED 24
+#define BATCH_RESERVED 36
 
 struct intel_batchbuffer;