From c289c70ce156e1248c53f018401a7670b9f513eb Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sat, 2 Nov 2013 20:58:10 -0700 Subject: [PATCH] i965: Start and stop OA counters as necessary. 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 Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/brw_context.h | 2 + .../dri/i965/brw_performance_monitor.c | 50 +++++++++++++++++++ src/mesa/drivers/dri/i965/intel_batchbuffer.c | 7 +++ src/mesa/drivers/dri/i965/intel_batchbuffer.h | 3 +- 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index cb92b282324..896f5c394f5 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -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); diff --git a/src/mesa/drivers/dri/i965/brw_performance_monitor.c b/src/mesa/drivers/dri/i965/brw_performance_monitor.c index 85c395b3aed..707deb24a9e 100644 --- a/src/mesa/drivers/dri/i965/brw_performance_monitor.c +++ b/src/mesa/drivers/dri/i965/brw_performance_monitor.c @@ -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) { diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index f66c2dd193a..99608dce9af 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -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); diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h index 861aed418bf..3b43ccfba13 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h @@ -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; -- 2.30.2