intel_perf_counters: Abstract out Ironlake-specific code.

We want to support this tool on more platforms.  This lays the
groundwork for making that possible.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Kenneth Graunke 2013-03-26 22:06:38 -07:00 committed by Daniel Vetter
parent 85667f4f7d
commit 0811556747

View File

@ -37,9 +37,9 @@
#include "intel_bufmgr.h" #include "intel_bufmgr.h"
#include "intel_batchbuffer.h" #include "intel_batchbuffer.h"
#define COUNTER_COUNT 29 #define GEN5_COUNTER_COUNT 29
const char *counter_name[COUNTER_COUNT] = { const char *gen5_counter_names[GEN5_COUNTER_COUNT] = {
"cycles the CS unit is starved", "cycles the CS unit is starved",
"cycles the CS unit is stalled", "cycles the CS unit is stalled",
"cycles the VF unit is starved", "cycles the VF unit is starved",
@ -72,13 +72,13 @@ const char *counter_name[COUNTER_COUNT] = {
}; };
int have_totals = 0; int have_totals = 0;
uint32_t totals[COUNTER_COUNT]; uint32_t *totals;
uint32_t last_counter[COUNTER_COUNT]; uint32_t *last_counter;
static drm_intel_bufmgr *bufmgr; static drm_intel_bufmgr *bufmgr;
struct intel_batchbuffer *batch; struct intel_batchbuffer *batch;
/* DW0 */ /* DW0 */
#define MI_REPORT_PERF_COUNT ((0x26 << 23) | (3 - 2)) #define GEN5_MI_REPORT_PERF_COUNT ((0x26 << 23) | (3 - 2))
#define MI_COUNTER_SET_0 (0 << 6) #define MI_COUNTER_SET_0 (0 << 6)
#define MI_COUNTER_SET_1 (1 << 6) #define MI_COUNTER_SET_1 (1 << 6)
/* DW1 */ /* DW1 */
@ -86,7 +86,7 @@ struct intel_batchbuffer *batch;
/* DW2: report ID */ /* DW2: report ID */
static void static void
get_counters(void) gen5_get_counters(void)
{ {
int i; int i;
drm_intel_bo *stats_bo; drm_intel_bo *stats_bo;
@ -95,13 +95,13 @@ get_counters(void)
stats_bo = drm_intel_bo_alloc(bufmgr, "stats", 4096, 4096); stats_bo = drm_intel_bo_alloc(bufmgr, "stats", 4096, 4096);
BEGIN_BATCH(6); BEGIN_BATCH(6);
OUT_BATCH(MI_REPORT_PERF_COUNT | MI_COUNTER_SET_0); OUT_BATCH(GEN5_MI_REPORT_PERF_COUNT | MI_COUNTER_SET_0);
OUT_RELOC(stats_bo, OUT_RELOC(stats_bo,
I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
0); 0);
OUT_BATCH(0); OUT_BATCH(0);
OUT_BATCH(MI_REPORT_PERF_COUNT | MI_COUNTER_SET_1); OUT_BATCH(GEN5_MI_REPORT_PERF_COUNT | MI_COUNTER_SET_1);
OUT_RELOC(stats_bo, OUT_RELOC(stats_bo,
I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
64); 64);
@ -115,7 +115,7 @@ get_counters(void)
stats_result = stats_bo->virtual; stats_result = stats_bo->virtual;
/* skip REPORT_ID, TIMESTAMP */ /* skip REPORT_ID, TIMESTAMP */
stats_result += 3; stats_result += 3;
for (i = 0 ; i < COUNTER_COUNT; i++) { for (i = 0 ; i < GEN5_COUNTER_COUNT; i++) {
totals[i] += stats_result[i] - last_counter[i]; totals[i] += stats_result[i] - last_counter[i];
last_counter[i] = stats_result[i]; last_counter[i] = stats_result[i];
} }
@ -131,6 +131,9 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
uint32_t devid; uint32_t devid;
int counter_count;
const char **counter_name;
void (*get_counters)(void);
int i; int i;
char clear_screen[] = {0x1b, '[', 'H', char clear_screen[] = {0x1b, '[', 'H',
0x1b, '[', 'J', 0x1b, '[', 'J',
@ -145,10 +148,16 @@ main(int argc, char **argv)
drm_intel_bufmgr_gem_enable_reuse(bufmgr); drm_intel_bufmgr_gem_enable_reuse(bufmgr);
batch = intel_batchbuffer_alloc(bufmgr, devid); batch = intel_batchbuffer_alloc(bufmgr, devid);
if (!IS_GEN5(devid)) { if (IS_GEN5(devid)) {
printf("This tool is only for Ironlake.\n"); counter_name = gen5_counter_names;
counter_count = GEN5_COUNTER_COUNT;
get_counters = gen5_get_counters;
} else {
printf("This tool is not yet supported on your platform.\n");
abort(); abort();
} }
totals = calloc(counter_count, sizeof(uint32_t));
last_counter = calloc(counter_count, sizeof(uint32_t));
for (;;) { for (;;) {
for (l = 0; l < STATS_CHECK_FREQUENCY; l++) { for (l = 0; l < STATS_CHECK_FREQUENCY; l++) {
@ -156,7 +165,7 @@ main(int argc, char **argv)
if (l % (STATS_CHECK_FREQUENCY / STATS_REPORT_FREQUENCY) == 0) { if (l % (STATS_CHECK_FREQUENCY / STATS_REPORT_FREQUENCY) == 0) {
if (have_totals) { if (have_totals) {
for (i = 0; i < COUNTER_COUNT; i++) { for (i = 0; i < counter_count; i++) {
printf("%s: %u\n", counter_name[i], printf("%s: %u\n", counter_name[i],
totals[i]); totals[i]);
totals[i] = 0; totals[i] = 0;
@ -171,5 +180,8 @@ main(int argc, char **argv)
} }
} }
free(totals);
free(last_counter);
return 0; return 0;
} }