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 <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Kenneth Graunke 2013-11-02 20:58:10 -07:00
parent 834c9575b2
commit c289c70ce1
4 changed files with 61 additions and 1 deletions

View 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);

View 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)
{

View 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);

View 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;