1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
enum pcounters {
PCNT_ALL,
PCNT_GPU,
PCNT_SPU,
PCNT_BLIT,
PCNT_GTE,
PCNT_TEST,
PCNT_CNT
};
#ifdef PCNT
#ifndef __ARM_ARCH_7A__
#include <sys/time.h>
#define PCNT_DIV 1
#else
#define PCNT_DIV 1000
#endif
static const char *pcnt_names[PCNT_CNT] = { "", "gpu", "spu", "blit", "gte", "test" };
#define PCNT_FRAMES 10
extern unsigned int pcounters[PCNT_CNT];
extern unsigned int pcounter_starts[PCNT_CNT];
#define pcnt_start(id) \
pcounter_starts[id] = pcnt_get()
#define pcnt_end(id) \
pcounters[id] += pcnt_get() - pcounter_starts[id]
void pcnt_hook_plugins(void);
static inline void pcnt_print(float fps)
{
static int print_counter;
unsigned int total, rem;
int i;
for (i = 0; i < PCNT_CNT; i++)
pcounters[i] /= PCNT_DIV * PCNT_FRAMES;
rem = total = pcounters[PCNT_ALL];
for (i = 1; i < PCNT_CNT; i++)
rem -= pcounters[i];
if (!total)
total++;
if (--print_counter < 0) {
printf(" ");
for (i = 1; i < PCNT_CNT; i++)
printf("%5s ", pcnt_names[i]);
printf("%5s\n", "rem");
print_counter = 30;
}
printf("%4.1f ", fps);
#if 0
static float pcounters_all[PCNT_CNT+1];
static int pcounter_samples;
pcounter_samples++;
for (i = 1; i < PCNT_CNT; i++) {
pcounters_all[i] += pcounters[i];
printf("%5.0f ", pcounters_all[i] / pcounter_samples);
}
pcounters_all[i] += rem;
printf("%5.0f\n", pcounters_all[i] / pcounter_samples);
#else
for (i = 1; i < PCNT_CNT; i++)
printf("%5u ", pcounters[i]);
printf("%5u (", rem);
for (i = 1; i < PCNT_CNT; i++)
printf("%2u ", pcounters[i] * 100 / total);
printf("%2u) %u\n", rem * 100 / total, total);
#endif
memset(pcounters, 0, sizeof(pcounters));
}
static inline unsigned int pcnt_get(void)
{
unsigned int val;
#ifdef __ARM_ARCH_7A__
__asm__ volatile("mrc p15, 0, %0, c9, c13, 0"
: "=r"(val));
#else
// all slow on ARM :(
//struct timespec tv;
//clock_gettime(CLOCK_MONOTONIC_RAW, &tv);
//val = tv.tv_sec * 1000000000 + tv.tv_nsec;
struct timeval tv;
gettimeofday(&tv, NULL);
val = tv.tv_sec * 1000000 + tv.tv_usec;
#endif
return val;
}
static inline void pcnt_init(void)
{
#ifdef __ARM_ARCH_7A__
int v;
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(v));
v |= 5; // master enable, ccnt reset
v &= ~8; // ccnt divider 0
asm volatile("mcr p15, 0, %0, c9, c12, 0" :: "r"(v));
// enable cycle counter
asm volatile("mcr p15, 0, %0, c9, c12, 1" :: "r"(1<<31));
#endif
}
void pcnt_gte_start(int op);
void pcnt_gte_end(int op);
#else
#define pcnt_start(id)
#define pcnt_end(id)
#define pcnt_hook_plugins()
#define pcnt_print(fps)
#endif
|