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