void kbopen(VOID) { kbinitmap(); if ((fptty = tfopen("/dev/tty","r")) != (FILE*)NULL) { set_terminal(); screen_lines = get_screen_lines(); } }
int main() { struct viv_conn *conn = 0; int rv; rv = viv_open(VIV_HW_3D, &conn); if(rv!=0) { fprintf(stderr, "Error opening device\n"); exit(1); } uint32_t num_profile_counters = viv_get_num_profile_counters(); /* XXX parameter parsing */ int samples_per_second = 100; bool interactive = true; int mode = MODE_ALL; //int mode = MODE_SORTED; bool color = true; uint32_t *counter_data = calloc(num_profile_counters, 4); uint32_t *counter_data_last = calloc(num_profile_counters, 4); uint64_t *events_per_s = calloc(num_profile_counters, 8); struct counter_rec *sorted = calloc(num_profile_counters, sizeof(struct counter_rec)); /* reset counters and initial values */ if(viv_read_profile_counters_3d(conn, counter_data_last) != 0) { fprintf(stderr, "Error querying counters (probably unsupported with this kernel, or not built into libetnaviv)\n"); exit(1); } uint32_t begin_time = gettime(); useconds_t interval = 1000000 / samples_per_second; while(true) { /* Scale counters by real elapsed time */ for(int c=0; c<num_profile_counters; ++c) { events_per_s[c] = 0; } for(int sample=0; sample<samples_per_second; ++sample) { if(viv_read_profile_counters_3d(conn, counter_data) != 0) { fprintf(stderr, "Error querying counters (probably unsupported with this kernel, or not built into libetnaviv)\n"); exit(1); } for(int c=0; c<num_profile_counters; ++c) { /* some counters don't reset when read */ if(c == VIV_PROF_PS_INST_COUNTER || c == VIV_PROF_VS_INST_COUNTER || c == VIV_PROF_RENDERED_PIXEL_COUNTER || c == VIV_PROF_RENDERED_VERTICE_COUNTER || c == VIV_PROF_PXL_TEXLD_INST_COUNTER || c == VIV_PROF_PXL_BRANCH_INST_COUNTER || c == VIV_PROF_VTX_TEXLD_INST_COUNTER || c == VIV_PROF_VTX_BRANCH_INST_COUNTER || c == VIV_PROF_SE_CULLED_TRIANGLE_COUNT || c == VIV_PROF_SE_CULLED_LINES_COUNT) events_per_s[c] += counter_data[c] - counter_data_last[c]; else events_per_s[c] += counter_data[c]; } for(int c=0; c<num_profile_counters; ++c) counter_data_last[c] = counter_data[c]; usleep(interval); } uint32_t end_time = gettime(); uint32_t diff_time = end_time - begin_time; /* Scale counters by real elapsed time */ for(int c=0; c<num_profile_counters; ++c) { events_per_s[c] = events_per_s[c] * 1000000LL / (uint64_t)diff_time; } /* Sort counters descending */ for(int c=0; c<num_profile_counters; ++c) { sorted[c].id = c; sorted[c].events_per_s = events_per_s[c]; } qsort(sorted, num_profile_counters, sizeof(struct counter_rec), &counter_rec_compar); if(interactive) { int line = 0; /* current screen line */ printf("%s", clear_screen); int max_lines = get_screen_lines() - line - 1; if(mode == MODE_SORTED) { int count = (num_profile_counters > max_lines) ? max_lines : num_profile_counters; for(int c=0; c<count; ++c) { char num[100]; struct viv_profile_counter_info *info = viv_get_profile_counter_info(sorted[c].id); format_number(num, sizeof(num), sorted[c].events_per_s); if(color) printf("%s", sorted[c].events_per_s == 0 ? color_num_zero : color_num); printf("%15.15s", num); if(color) printf("%s", color_reset); printf(" "); printf("%-30.30s", info->name); printf("\n"); } } else if(mode == MODE_ALL) { /* XXX check that width doesn't exceed screen width */ for(int l=0; l<max_lines; ++l) { int c = VIV_PROF_GPU_CYCLES_COUNTER + l; while(c < num_profile_counters) { char num[100]; struct viv_profile_counter_info *info = viv_get_profile_counter_info(c); format_number(num, sizeof(num), events_per_s[c]); if(color) printf("%s", events_per_s[c] == 0 ? color_num_zero : color_num); printf("%15.15s", num); if(color) printf("%s", color_reset); printf(" "); printf("%-30.30s", info->name); printf(" "); c += max_lines; } printf("\n"); } } } begin_time = end_time; } /* * XXX define new mode MODE_OCCUPANCY and some derived percentage bars: * - [PA] Number of primitives per vertex (max 1) * - [PA] % of primitives culled * - VS -> PA -> SE -> RA primitives/vertices in each stage * - RA -> PS -> PE pixels/quads in each stage * - Pixels per PS inst * - Vertices per VS inst * - % of texture requests trilinear/bilinear * - overdraw (killed by depth) */ return 0; }