diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-21 20:13:10 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-21 20:13:10 +0200 |
commit | ad741838d5e39d6874a44b1e609c70b486a3ac21 (patch) | |
tree | 35544db5d7d4388a5cc8a935fd1abe218f2db48e | |
parent | 9db4c23d3c8c7d2cbf6b65ff123a25dc48ae51eb (diff) | |
download | gba-link-cable-tester-ad741838d5e39d6874a44b1e609c70b486a3ac21.tar.gz gba-link-cable-tester-ad741838d5e39d6874a44b1e609c70b486a3ac21.zip |
Add text rendering benchmark and better prof control
-rw-r--r-- | src/main.c | 32 | ||||
-rw-r--r-- | src/profiling.c | 165 | ||||
-rw-r--r-- | src/text/text.h | 19 |
3 files changed, 150 insertions, 66 deletions
@@ -291,6 +291,37 @@ test_sprites_bounce(void) { | |||
291 | } | 291 | } |
292 | } | 292 | } |
293 | 293 | ||
294 | void | ||
295 | test_text_rendering(void) { | ||
296 | while (true) { | ||
297 | poll_keys(); | ||
298 | if (key_tap(KEY_A)) { | ||
299 | break; | ||
300 | } | ||
301 | bios_vblank_wait(); | ||
302 | FRAME_START(); | ||
303 | PROF(flip_buffer(), flip_cycles); | ||
304 | PROF(screen_fill(0), clear_cycles); | ||
305 | txt_color(2); | ||
306 | txt_position(0, 8); | ||
307 | PROF(txt_drawf("The strongest bulwark of", 4, 0, 3), txt_drawf_cycles); | ||
308 | PROF(txt_drawf("authority is uniformity;", 2, 8, 3), txt_drawf_cycles); | ||
309 | PROF(txt_drawf("the least divergence from it", 8, 16, 3), txt_drawf_cycles); | ||
310 | PROF(txt_drawf("it's the greatest crime", 6, 24, 3), txt_drawf_cycles); | ||
311 | PROF(txt_drawf("- Emma Goldman", 100, 36, 3), txt_drawf_cycles); | ||
312 | PROF(txt_printf("The only way to deal with an\n" | ||
313 | "unfree world is to become\n" | ||
314 | "so absolutely free,\n" | ||
315 | "that your very existence\n" | ||
316 | "is an act of rebellion.\n"), txt_printf_cycles); | ||
317 | PROF(txt_printf("\n - Albert Camus\n"), txt_printf_cycles); | ||
318 | PROF(txt_render(), txt_render_cycles); | ||
319 | PROF(txt_clear(), txt_clear_cycles); | ||
320 | FRAME_END(); | ||
321 | PROF_SHOW(); | ||
322 | } | ||
323 | } | ||
324 | |||
294 | int main(void) { | 325 | int main(void) { |
295 | // Adjust system wait times. | 326 | // Adjust system wait times. |
296 | SYSTEM_WAIT = SYSTEM_WAIT_CARTRIDGE; | 327 | SYSTEM_WAIT = SYSTEM_WAIT_CARTRIDGE; |
@@ -306,6 +337,7 @@ int main(void) { | |||
306 | // TODO: Add a clear mode for chr that inverts non zero values to become | 337 | // TODO: Add a clear mode for chr that inverts non zero values to become |
307 | // zero, thus clearing the sprite if it was in the same position. | 338 | // zero, thus clearing the sprite if it was in the same position. |
308 | while (true) { | 339 | while (true) { |
340 | test_text_rendering(); | ||
309 | test_growing_rects(); | 341 | test_growing_rects(); |
310 | test_sprites_bounce(); | 342 | test_sprites_bounce(); |
311 | test_moving_line(); | 343 | test_moving_line(); |
diff --git a/src/profiling.c b/src/profiling.c index 89e2ce7..1686ad9 100644 --- a/src/profiling.c +++ b/src/profiling.c | |||
@@ -40,61 +40,98 @@ | |||
40 | #define PROF_SHOW_Y 0 | 40 | #define PROF_SHOW_Y 0 |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | static bool profile_show = true; | ||
44 | static bool profile_bg_show = true; | ||
45 | |||
43 | #define PROF_SHOW() \ | 46 | #define PROF_SHOW() \ |
44 | do { \ | 47 | do { \ |
45 | txt_position((PROF_SHOW_X), (PROF_SHOW_Y));\ | 48 | if (key_tap(KEY_START)) {\ |
46 | txt_printf("CLEAR %.8lu\n", avg_clear_cycles);\ | 49 | profile_show ^= 1;\ |
47 | txt_printf("LINES %.8lu\n", avg_line_cycles);\ | 50 | }\ |
48 | txt_printf("RECT %.8lu\n", avg_rect_cycles);\ | 51 | if (key_tap(KEY_SELECT)) {\ |
49 | txt_printf("FRECT %.8lu\n", avg_fill_rect_cycles);\ | 52 | profile_bg_show ^= 1;\ |
50 | txt_printf("1BPP %.8lu\n", avg_icn_cycles);\ | 53 | }\ |
51 | txt_printf("2BPP %.8lu\n", avg_chr_cycles);\ | 54 | if (profile_show) {\ |
52 | txt_printf("FLIP %.8lu\n", avg_flip_cycles);\ | 55 | txt_color(1);\ |
53 | txt_printf("TOTAL %.8lu\n", avg_frame_cycles);\ | 56 | txt_position((PROF_SHOW_X), (PROF_SHOW_Y));\ |
54 | txt_render();\ | 57 | if (profile_bg_show) {\ |
58 | draw_filled_rect((PROF_SHOW_X), (PROF_SHOW_X), 8 * 17, 8 * 14, 0);\ | ||
59 | }\ | ||
60 | txt_printf("VIDEO\n");\ | ||
61 | txt_printf(">CLEAR %.8lu\n", avg_clear_cycles);\ | ||
62 | txt_printf(">LINES %.8lu\n", avg_line_cycles);\ | ||
63 | txt_printf(">RECT %.8lu\n", avg_rect_cycles);\ | ||
64 | txt_printf(">FRECT %.8lu\n", avg_fill_rect_cycles);\ | ||
65 | txt_printf(">1BPP %.8lu\n", avg_icn_cycles);\ | ||
66 | txt_printf(">2BPP %.8lu\n", avg_chr_cycles);\ | ||
67 | txt_printf(">FLIP %.8lu\n", avg_flip_cycles);\ | ||
68 | txt_printf("TEXT\n");\ | ||
69 | txt_printf(">DRAWF %.8lu\n", avg_txt_drawf_cycles);\ | ||
70 | txt_printf(">PRINTF %.8lu\n", avg_txt_printf_cycles);\ | ||
71 | txt_printf(">RENDER %.8lu\n", avg_txt_render_cycles);\ | ||
72 | txt_printf(">CLEAR %.8lu\n", avg_txt_clear_cycles);\ | ||
73 | txt_printf("TOTAL %.8lu\n", avg_frame_cycles);\ | ||
74 | txt_render();\ | ||
75 | }\ | ||
55 | } while (0) | 76 | } while (0) |
56 | 77 | ||
57 | static u32 prof_frame_counter = 0; | 78 | static u32 prof_frame_counter = 0; |
58 | 79 | ||
59 | static u32 frame_cycles = 0; | 80 | static u32 frame_cycles = 0; |
60 | static u32 flip_cycles = 0; | 81 | static u32 flip_cycles = 0; |
61 | static u32 clear_cycles = 0; | 82 | static u32 clear_cycles = 0; |
62 | static u32 line_cycles = 0; | 83 | static u32 line_cycles = 0; |
63 | static u32 rect_cycles = 0; | 84 | static u32 rect_cycles = 0; |
64 | static u32 fill_rect_cycles = 0; | 85 | static u32 fill_rect_cycles = 0; |
65 | static u32 chr_cycles = 0; | 86 | static u32 chr_cycles = 0; |
66 | static u32 icn_cycles = 0; | 87 | static u32 icn_cycles = 0; |
88 | static u32 txt_drawf_cycles = 0; | ||
89 | static u32 txt_printf_cycles = 0; | ||
90 | static u32 txt_render_cycles = 0; | ||
91 | static u32 txt_clear_cycles = 0; | ||
67 | 92 | ||
68 | static u32 avg_frame_cycles = 0; | 93 | static u32 avg_frame_cycles = 0; |
69 | static u32 avg_flip_cycles = 0; | 94 | static u32 avg_flip_cycles = 0; |
70 | static u32 avg_clear_cycles = 0; | 95 | static u32 avg_clear_cycles = 0; |
71 | static u32 avg_line_cycles = 0; | 96 | static u32 avg_line_cycles = 0; |
72 | static u32 avg_rect_cycles = 0; | 97 | static u32 avg_rect_cycles = 0; |
73 | static u32 avg_fill_rect_cycles = 0; | 98 | static u32 avg_fill_rect_cycles = 0; |
74 | static u32 avg_chr_cycles = 0; | 99 | static u32 avg_chr_cycles = 0; |
75 | static u32 avg_icn_cycles = 0; | 100 | static u32 avg_icn_cycles = 0; |
101 | static u32 avg_txt_drawf_cycles = 0; | ||
102 | static u32 avg_txt_printf_cycles = 0; | ||
103 | static u32 avg_txt_render_cycles = 0; | ||
104 | static u32 avg_txt_clear_cycles = 0; | ||
76 | 105 | ||
77 | #if PROF_ENABLE == 1 | 106 | #if PROF_ENABLE == 1 |
78 | #define FRAME_START()\ | 107 | #define FRAME_START()\ |
79 | do { \ | 108 | do { \ |
80 | if (prof_frame_counter == PROF_N_FRAMES) {\ | 109 | if (prof_frame_counter == PROF_N_FRAMES) {\ |
81 | avg_frame_cycles = frame_cycles / prof_frame_counter;\ | 110 | avg_frame_cycles = frame_cycles / prof_frame_counter;\ |
82 | avg_flip_cycles = flip_cycles / prof_frame_counter;\ | 111 | avg_flip_cycles = flip_cycles / prof_frame_counter;\ |
83 | avg_clear_cycles = clear_cycles / prof_frame_counter;\ | 112 | avg_clear_cycles = clear_cycles / prof_frame_counter;\ |
84 | avg_line_cycles = line_cycles / prof_frame_counter;\ | 113 | avg_line_cycles = line_cycles / prof_frame_counter;\ |
85 | avg_rect_cycles = rect_cycles / prof_frame_counter;\ | 114 | avg_rect_cycles = rect_cycles / prof_frame_counter;\ |
86 | avg_fill_rect_cycles = fill_rect_cycles / prof_frame_counter;\ | 115 | avg_fill_rect_cycles = fill_rect_cycles / prof_frame_counter;\ |
87 | avg_chr_cycles = chr_cycles / prof_frame_counter;\ | 116 | avg_chr_cycles = chr_cycles / prof_frame_counter;\ |
88 | avg_icn_cycles = icn_cycles / prof_frame_counter;\ | 117 | avg_icn_cycles = icn_cycles / prof_frame_counter;\ |
89 | frame_cycles = 0;\ | 118 | avg_txt_drawf_cycles = txt_drawf_cycles / prof_frame_counter;\ |
90 | flip_cycles = 0;\ | 119 | avg_txt_printf_cycles = txt_printf_cycles / prof_frame_counter;\ |
91 | clear_cycles = 0;\ | 120 | avg_txt_render_cycles = txt_render_cycles / prof_frame_counter;\ |
92 | line_cycles = 0;\ | 121 | avg_txt_clear_cycles = txt_clear_cycles / prof_frame_counter;\ |
93 | rect_cycles = 0;\ | 122 | frame_cycles = 0;\ |
94 | fill_rect_cycles = 0;\ | 123 | flip_cycles = 0;\ |
95 | chr_cycles = 0;\ | 124 | clear_cycles = 0;\ |
96 | icn_cycles = 0;\ | 125 | line_cycles = 0;\ |
97 | prof_frame_counter = 0;\ | 126 | rect_cycles = 0;\ |
127 | fill_rect_cycles = 0;\ | ||
128 | chr_cycles = 0;\ | ||
129 | icn_cycles = 0;\ | ||
130 | txt_drawf_cycles = 0;\ | ||
131 | txt_printf_cycles = 0;\ | ||
132 | txt_render_cycles = 0;\ | ||
133 | txt_clear_cycles = 0;\ | ||
134 | prof_frame_counter = 0;\ | ||
98 | }\ | 135 | }\ |
99 | profile_start();\ | 136 | profile_start();\ |
100 | } while (0) | 137 | } while (0) |
@@ -102,23 +139,31 @@ static u32 avg_icn_cycles = 0; | |||
102 | #define FRAME_START()\ | 139 | #define FRAME_START()\ |
103 | do { \ | 140 | do { \ |
104 | if (prof_frame_counter == PROF_N_FRAMES) {\ | 141 | if (prof_frame_counter == PROF_N_FRAMES) {\ |
105 | avg_frame_cycles = frame_cycles;\ | 142 | avg_frame_cycles = frame_cycles;\ |
106 | avg_flip_cycles = flip_cycles;\ | 143 | avg_flip_cycles = flip_cycles;\ |
107 | avg_clear_cycles = clear_cycles;\ | 144 | avg_clear_cycles = clear_cycles;\ |
108 | avg_line_cycles = line_cycles;\ | 145 | avg_line_cycles = line_cycles;\ |
109 | avg_rect_cycles = rect_cycles;\ | 146 | avg_rect_cycles = rect_cycles;\ |
110 | avg_fill_rect_cycles = fill_rect_cycles;\ | 147 | avg_fill_rect_cycles = fill_rect_cycles;\ |
111 | avg_chr_cycles = chr_cycles;\ | 148 | avg_chr_cycles = chr_cycles;\ |
112 | avg_icn_cycles = icn_cycles;\ | 149 | avg_icn_cycles = icn_cycles;\ |
113 | frame_cycles = 0;\ | 150 | avg_txt_drawf_cycles = txt_drawf_cycles;\ |
114 | flip_cycles = 0;\ | 151 | avg_txt_printf_cycles = txt_printf_cycles;\ |
115 | clear_cycles = 0;\ | 152 | avg_txt_render_cycles = txt_render_cycles;\ |
116 | line_cycles = 0;\ | 153 | avg_txt_clear_cycles = txt_clear_cycles;\ |
117 | rect_cycles = 0;\ | 154 | frame_cycles = 0;\ |
118 | fill_rect_cycles = 0;\ | 155 | flip_cycles = 0;\ |
119 | chr_cycles = 0;\ | 156 | clear_cycles = 0;\ |
120 | icn_cycles = 0;\ | 157 | line_cycles = 0;\ |
121 | prof_frame_counter = 0;\ | 158 | rect_cycles = 0;\ |
159 | fill_rect_cycles = 0;\ | ||
160 | chr_cycles = 0;\ | ||
161 | icn_cycles = 0;\ | ||
162 | txt_drawf_cycles = 0;\ | ||
163 | txt_printf_cycles = 0;\ | ||
164 | txt_render_cycles = 0;\ | ||
165 | txt_clear_cycles = 0;\ | ||
166 | prof_frame_counter = 0;\ | ||
122 | }\ | 167 | }\ |
123 | profile_start();\ | 168 | profile_start();\ |
124 | } while (0) | 169 | } while (0) |
diff --git a/src/text/text.h b/src/text/text.h index 4f66058..24573f8 100644 --- a/src/text/text.h +++ b/src/text/text.h | |||
@@ -61,12 +61,9 @@ txt_puts(char *msg) { | |||
61 | static inline | 61 | static inline |
62 | void | 62 | void |
63 | txt_clear_line(void) { | 63 | txt_clear_line(void) { |
64 | for (size_t i = 0; i < 30; ++i) { | 64 | dma_fill(text_engine.buffer, 0, sizeof(text_engine.buffer), 3); |
65 | int x = text_engine.cursor_x; | ||
66 | int y = text_engine.cursor_y; | ||
67 | text_engine.buffer[x + 30 * y] = 0; | ||
68 | } | ||
69 | text_engine.cursor_x = 0; | 65 | text_engine.cursor_x = 0; |
66 | text_engine.cursor_y = 0; | ||
70 | } | 67 | } |
71 | 68 | ||
72 | // Clears the screen on the tile text mode. | 69 | // Clears the screen on the tile text mode. |
@@ -89,13 +86,23 @@ txt_position(size_t tile_x, size_t tile_y) { | |||
89 | text_engine.cursor_y = tile_y; | 86 | text_engine.cursor_y = tile_y; |
90 | } | 87 | } |
91 | 88 | ||
89 | static inline | ||
90 | void | ||
91 | txt_color(u8 clr) { | ||
92 | text_engine.color = clr; | ||
93 | } | ||
94 | |||
92 | // Renders the contents of the scrollback buffer to the screen. | 95 | // Renders the contents of the scrollback buffer to the screen. |
93 | void | 96 | void |
94 | txt_render(void) { | 97 | txt_render(void) { |
95 | for (size_t y = 0; y < 20; y++) { | 98 | for (size_t y = 0; y < 20; y++) { |
96 | for (size_t x = 0; x < 30; x++) { | 99 | for (size_t x = 0; x < 30; x++) { |
100 | size_t pos = x + y * 30; | ||
101 | if (text_engine.buffer[pos] == 0) { | ||
102 | continue; | ||
103 | } | ||
97 | text_engine.drawc( | 104 | text_engine.drawc( |
98 | text_engine.buffer[x + y * 30], | 105 | text_engine.buffer[pos], |
99 | x * text_engine.spacing, | 106 | x * text_engine.spacing, |
100 | y * text_engine.spacing, | 107 | y * text_engine.spacing, |
101 | text_engine.color); | 108 | text_engine.color); |