diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-21 17:40:04 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-21 17:40:04 +0200 |
commit | 53580f3695f6f53f2fc0ecea169609bc9d853643 (patch) | |
tree | 55682186f5c081fb78e4afedf9e90f83c9a7f529 | |
parent | bd523af5fb49ec78073a35ce63d53ba5c32064d0 (diff) | |
download | gba-link-cable-tester-53580f3695f6f53f2fc0ecea169609bc9d853643.tar.gz gba-link-cable-tester-53580f3695f6f53f2fc0ecea169609bc9d853643.zip |
Add new profiling macros
-rw-r--r-- | src/gba/gba.h | 4 | ||||
-rw-r--r-- | src/main.c | 88 | ||||
-rw-r--r-- | src/profiling.c | 140 | ||||
-rw-r--r-- | src/renderer_m0.c | 2 |
4 files changed, 184 insertions, 50 deletions
diff --git a/src/gba/gba.h b/src/gba/gba.h index 99eb1f7..27a6a9a 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h | |||
@@ -419,6 +419,8 @@ inline | |||
419 | void | 419 | void |
420 | dma_copy(void *dst, const void *src, u32 size, int channel) { | 420 | dma_copy(void *dst, const void *src, u32 size, int channel) { |
421 | dma_transfer_copy(dst, src, size / 4, channel, DMA_CHUNK_32 | DMA_ENABLE); | 421 | dma_transfer_copy(dst, src, size / 4, channel, DMA_CHUNK_32 | DMA_ENABLE); |
422 | // Stall for 2 cycles in case we call this function more than once. | ||
423 | asm("nop"); asm("nop"); | ||
422 | } | 424 | } |
423 | 425 | ||
424 | // Fill the dst location with the word set at src. | 426 | // Fill the dst location with the word set at src. |
@@ -426,6 +428,8 @@ inline | |||
426 | void | 428 | void |
427 | dma_fill(void *dst, vu32 src, u32 size, int channel) { | 429 | dma_fill(void *dst, vu32 src, u32 size, int channel) { |
428 | dma_transfer_fill(dst, src, size / 4, channel, DMA_CHUNK_32 | DMA_ENABLE); | 430 | dma_transfer_fill(dst, src, size / 4, channel, DMA_CHUNK_32 | DMA_ENABLE); |
431 | // Stall for 2 cycles in case we call this function more than once. | ||
432 | asm("nop"); asm("nop"); | ||
429 | } | 433 | } |
430 | 434 | ||
431 | // | 435 | // |
@@ -11,45 +11,14 @@ WITH REGARD TO THIS SOFTWARE. | |||
11 | 11 | ||
12 | #include "gba/gba.h" | 12 | #include "gba/gba.h" |
13 | 13 | ||
14 | #include "renderer_m0.c" | 14 | #include "renderer_m4.c" |
15 | 15 | ||
16 | // | 16 | // |
17 | // Config parameters. | 17 | // Config parameters. |
18 | // | 18 | // |
19 | 19 | ||
20 | #if PROF_ENABLE == 0 | 20 | #define PROF_ENABLE 1 |
21 | #define PROF(F,VAR) (profile_start(),(F),(VAR) = profile_stop()) | 21 | #include "profiling.c" |
22 | #else | ||
23 | #define PROF(F,VAR) (profile_start(),(F),(VAR) = MAX(profile_stop(), (VAR))) | ||
24 | #endif | ||
25 | #ifndef PROF_SHOW_X | ||
26 | #define PROF_SHOW_X 0 | ||
27 | #endif | ||
28 | #ifndef PROF_SHOW_Y | ||
29 | #define PROF_SHOW_Y 0 | ||
30 | #endif | ||
31 | #define PROF_SHOW() \ | ||
32 | do {\ | ||
33 | txt_printf("RECT: %.9lu\n", test_rect_cycles);\ | ||
34 | txt_printf("FRECT: %.9lu\n", test_fill_rect_cycles);\ | ||
35 | txt_printf("CLEAR: %.9lu\n", test_clear_cycles);\ | ||
36 | txt_printf("FLIP: %.9lu\n", flip_cycles);\ | ||
37 | txt_printf("CHR: %.9lu\n", test_chr_cycles);\ | ||
38 | txt_printf("ICN: %.9lu\n", test_icn_cycles);\ | ||
39 | txt_printf("LINE: %.9lu\n", test_lines_cycles);\ | ||
40 | txt_render();\ | ||
41 | txt_clear();\ | ||
42 | frame_counter++;\ | ||
43 | } while (0) | ||
44 | #define PROF_INIT() \ | ||
45 | u32 frame_counter = 0;\ | ||
46 | u32 test_fill_rect_cycles = 0;\ | ||
47 | u32 test_rect_cycles = 0;\ | ||
48 | u32 test_clear_cycles = 0;\ | ||
49 | u32 test_chr_cycles = 0;\ | ||
50 | u32 test_icn_cycles = 0;\ | ||
51 | u32 test_lines_cycles = 0;\ | ||
52 | u32 flip_cycles = 0; | ||
53 | 22 | ||
54 | void | 23 | void |
55 | test_clear(void) { | 24 | test_clear(void) { |
@@ -116,8 +85,15 @@ test_moving_line(void) { | |||
116 | int inc_x = 1; | 85 | int inc_x = 1; |
117 | int inc_y = 0; | 86 | int inc_y = 0; |
118 | while (true) { | 87 | while (true) { |
119 | screen_fill(0); | 88 | poll_keys(); |
120 | draw_line(x, y, 239 - x, 159 - y, 2); | 89 | if (key_tap(KEY_A)) { |
90 | break; | ||
91 | } | ||
92 | bios_vblank_wait(); | ||
93 | FRAME_START(); | ||
94 | PROF(flip_buffer(), flip_cycles); | ||
95 | PROF(screen_fill(3), clear_cycles); | ||
96 | PROF(draw_line(x, y, 239 - x, 159 - y, 2), line_cycles); | ||
121 | x += inc_x; | 97 | x += inc_x; |
122 | y += inc_y; | 98 | y += inc_y; |
123 | if (x == 239 && inc_x == 1) { | 99 | if (x == 239 && inc_x == 1) { |
@@ -130,8 +106,29 @@ test_moving_line(void) { | |||
130 | inc_x = 1; | 106 | inc_x = 1; |
131 | inc_y = 0; | 107 | inc_y = 0; |
132 | } | 108 | } |
109 | FRAME_END(); | ||
110 | PROF_SHOW(); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | void | ||
115 | test_all_static(void) { | ||
116 | while (true) { | ||
117 | poll_keys(); | ||
118 | if (key_tap(KEY_A)) { | ||
119 | break; | ||
120 | } | ||
133 | bios_vblank_wait(); | 121 | bios_vblank_wait(); |
134 | flip_buffer(); | 122 | FRAME_START(); |
123 | PROF(flip_buffer(), flip_cycles); | ||
124 | PROF(test_clear(), clear_cycles); | ||
125 | PROF(test_lines(), line_cycles); | ||
126 | PROF(test_rect(), rect_cycles); | ||
127 | PROF(test_fill_rect(), fill_rect_cycles); | ||
128 | PROF(test_chr(), chr_cycles); | ||
129 | PROF(test_icn(), icn_cycles); | ||
130 | FRAME_END(); | ||
131 | PROF_SHOW(); | ||
135 | } | 132 | } |
136 | } | 133 | } |
137 | 134 | ||
@@ -146,19 +143,12 @@ int main(void) { | |||
146 | irq_init(); | 143 | irq_init(); |
147 | irs_set(IRQ_VBLANK, irs_stub); | 144 | irs_set(IRQ_VBLANK, irs_stub); |
148 | 145 | ||
149 | // Main loop. | 146 | // TODO: Test sprites in movement. |
150 | PROF_INIT(); | 147 | // TODO: Verify all works well, there were some modifications and |
148 | // bugfixes on the ppu of the uxngba branch. | ||
151 | while (true) { | 149 | while (true) { |
152 | PROF(test_clear(), test_clear_cycles); | 150 | test_moving_line(); |
153 | PROF(test_lines(), test_lines_cycles); | 151 | test_all_static(); |
154 | PROF(test_rect(), test_rect_cycles); | ||
155 | PROF(test_fill_rect(), test_fill_rect_cycles); | ||
156 | PROF(test_chr(), test_chr_cycles); | ||
157 | PROF(test_icn(), test_icn_cycles); | ||
158 | draw_filled_rect(0, 0, 140, 60, 0); | ||
159 | PROF_SHOW(); | ||
160 | bios_vblank_wait(); | ||
161 | PROF(flip_buffer(), flip_cycles); | ||
162 | } | 152 | } |
163 | 153 | ||
164 | return 0; | 154 | return 0; |
diff --git a/src/profiling.c b/src/profiling.c new file mode 100644 index 0000000..89e2ce7 --- /dev/null +++ b/src/profiling.c | |||
@@ -0,0 +1,140 @@ | |||
1 | // | ||
2 | // Profiling macros. | ||
3 | // | ||
4 | |||
5 | #ifndef PROF_ENABLE | ||
6 | #define PROF_ENABLE 0 | ||
7 | #endif | ||
8 | |||
9 | #if PROF_ENABLE > 0 && PROF_ENABLE < 3 | ||
10 | |||
11 | #ifndef PROF_N_FRAMES | ||
12 | #define PROF_N_FRAMES 5 | ||
13 | #endif | ||
14 | |||
15 | // Profile method 1: Average per N frames. | ||
16 | #if PROF_ENABLE == 1 | ||
17 | #define TEXT_ENABLE 1 | ||
18 | #define PROF(F,VAR) \ | ||
19 | do { \ | ||
20 | u32 __tmp_prof = profile_measure();\ | ||
21 | (F);\ | ||
22 | (VAR) += profile_measure() - __tmp_prof;\ | ||
23 | } while (0) | ||
24 | |||
25 | // Profile method 2: Maximum in N frames. | ||
26 | #elif PROF_ENABLE == 2 | ||
27 | #define TEXT_ENABLE 1 | ||
28 | #define PROF(F,VAR) \ | ||
29 | do { \ | ||
30 | u32 __tmp_prof = profile_measure();\ | ||
31 | (F);\ | ||
32 | (VAR) = MAX(profile_measure() - __tmp_prof, (VAR));\ | ||
33 | } while (0) | ||
34 | #endif | ||
35 | |||
36 | #ifndef PROF_SHOW_X | ||
37 | #define PROF_SHOW_X 0 | ||
38 | #endif | ||
39 | #ifndef PROF_SHOW_Y | ||
40 | #define PROF_SHOW_Y 0 | ||
41 | #endif | ||
42 | |||
43 | #define PROF_SHOW() \ | ||
44 | do { \ | ||
45 | txt_position((PROF_SHOW_X), (PROF_SHOW_Y));\ | ||
46 | txt_printf("CLEAR %.8lu\n", avg_clear_cycles);\ | ||
47 | txt_printf("LINES %.8lu\n", avg_line_cycles);\ | ||
48 | txt_printf("RECT %.8lu\n", avg_rect_cycles);\ | ||
49 | txt_printf("FRECT %.8lu\n", avg_fill_rect_cycles);\ | ||
50 | txt_printf("1BPP %.8lu\n", avg_icn_cycles);\ | ||
51 | txt_printf("2BPP %.8lu\n", avg_chr_cycles);\ | ||
52 | txt_printf("FLIP %.8lu\n", avg_flip_cycles);\ | ||
53 | txt_printf("TOTAL %.8lu\n", avg_frame_cycles);\ | ||
54 | txt_render();\ | ||
55 | } while (0) | ||
56 | |||
57 | static u32 prof_frame_counter = 0; | ||
58 | |||
59 | static u32 frame_cycles = 0; | ||
60 | static u32 flip_cycles = 0; | ||
61 | static u32 clear_cycles = 0; | ||
62 | static u32 line_cycles = 0; | ||
63 | static u32 rect_cycles = 0; | ||
64 | static u32 fill_rect_cycles = 0; | ||
65 | static u32 chr_cycles = 0; | ||
66 | static u32 icn_cycles = 0; | ||
67 | |||
68 | static u32 avg_frame_cycles = 0; | ||
69 | static u32 avg_flip_cycles = 0; | ||
70 | static u32 avg_clear_cycles = 0; | ||
71 | static u32 avg_line_cycles = 0; | ||
72 | static u32 avg_rect_cycles = 0; | ||
73 | static u32 avg_fill_rect_cycles = 0; | ||
74 | static u32 avg_chr_cycles = 0; | ||
75 | static u32 avg_icn_cycles = 0; | ||
76 | |||
77 | #if PROF_ENABLE == 1 | ||
78 | #define FRAME_START()\ | ||
79 | do { \ | ||
80 | if (prof_frame_counter == PROF_N_FRAMES) {\ | ||
81 | avg_frame_cycles = frame_cycles / prof_frame_counter;\ | ||
82 | avg_flip_cycles = flip_cycles / prof_frame_counter;\ | ||
83 | avg_clear_cycles = clear_cycles / prof_frame_counter;\ | ||
84 | avg_line_cycles = line_cycles / prof_frame_counter;\ | ||
85 | avg_rect_cycles = rect_cycles / prof_frame_counter;\ | ||
86 | avg_fill_rect_cycles = fill_rect_cycles / prof_frame_counter;\ | ||
87 | avg_chr_cycles = chr_cycles / prof_frame_counter;\ | ||
88 | avg_icn_cycles = icn_cycles / prof_frame_counter;\ | ||
89 | frame_cycles = 0;\ | ||
90 | flip_cycles = 0;\ | ||
91 | clear_cycles = 0;\ | ||
92 | line_cycles = 0;\ | ||
93 | rect_cycles = 0;\ | ||
94 | fill_rect_cycles = 0;\ | ||
95 | chr_cycles = 0;\ | ||
96 | icn_cycles = 0;\ | ||
97 | prof_frame_counter = 0;\ | ||
98 | }\ | ||
99 | profile_start();\ | ||
100 | } while (0) | ||
101 | #elif PROF_ENABLE == 2 | ||
102 | #define FRAME_START()\ | ||
103 | do { \ | ||
104 | if (prof_frame_counter == PROF_N_FRAMES) {\ | ||
105 | avg_frame_cycles = frame_cycles;\ | ||
106 | avg_flip_cycles = flip_cycles;\ | ||
107 | avg_clear_cycles = clear_cycles;\ | ||
108 | avg_line_cycles = line_cycles;\ | ||
109 | avg_rect_cycles = rect_cycles;\ | ||
110 | avg_fill_rect_cycles = fill_rect_cycles;\ | ||
111 | avg_chr_cycles = chr_cycles;\ | ||
112 | avg_icn_cycles = icn_cycles;\ | ||
113 | frame_cycles = 0;\ | ||
114 | flip_cycles = 0;\ | ||
115 | clear_cycles = 0;\ | ||
116 | line_cycles = 0;\ | ||
117 | rect_cycles = 0;\ | ||
118 | fill_rect_cycles = 0;\ | ||
119 | chr_cycles = 0;\ | ||
120 | icn_cycles = 0;\ | ||
121 | prof_frame_counter = 0;\ | ||
122 | }\ | ||
123 | profile_start();\ | ||
124 | } while (0) | ||
125 | #endif | ||
126 | |||
127 | #define FRAME_END() \ | ||
128 | do { \ | ||
129 | prof_frame_counter++;\ | ||
130 | frame_cycles += profile_stop();\ | ||
131 | } while (0) | ||
132 | |||
133 | #else | ||
134 | |||
135 | // No profiling. | ||
136 | #define PROF(F,VAR) (F) | ||
137 | #define PROF_SHOW() | ||
138 | #define FRAME_START() | ||
139 | #define FRAME_END() | ||
140 | #endif | ||
diff --git a/src/renderer_m0.c b/src/renderer_m0.c index 35e9ceb..eaf4658 100644 --- a/src/renderer_m0.c +++ b/src/renderer_m0.c | |||
@@ -12,7 +12,7 @@ | |||
12 | // Parameters. | 12 | // Parameters. |
13 | // | 13 | // |
14 | 14 | ||
15 | #define SUBPIXEL_LINES 0 | 15 | #define SUBPIXEL_LINES 1 |
16 | #define DEC_BIG_LUT 1 | 16 | #define DEC_BIG_LUT 1 |
17 | 17 | ||
18 | // Front/back buffers for double buffering. | 18 | // Front/back buffers for double buffering. |