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
124
125
126
127
128
129
130
131
132
133
134
135
136
|
#ifndef __PCNT_H__
#define __PCNT_H__
enum pcounters {
PCNT_ALL,
PCNT_GPU,
PCNT_SPU,
PCNT_BLIT,
PCNT_GTE,
PCNT_TEST,
PCNT_CNT
};
#ifdef PCNT
#if defined(__ARM_ARCH_7A__) || defined(ARM1176)
#define PCNT_DIV 1000
#else
#include <sys/time.h>
#define PCNT_DIV 1
#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));
#elif defined(ARM1176)
__asm__ volatile("mrc p15, 0, %0, c15, c12, 1"
: "=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));
#elif defined(ARM1176)
int v;
asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(v));
v |= 5; // master enable, ccnt reset
v &= ~8; // ccnt divider 0
asm volatile("mcr p15, 0, %0, c15, c12, 0" :: "r"(v));
#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
#endif /* __PCNT_H__ */
|