summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-04-21 17:40:04 +0200
committerBad Diode <bd@badd10de.dev>2023-04-21 17:40:04 +0200
commit53580f3695f6f53f2fc0ecea169609bc9d853643 (patch)
tree55682186f5c081fb78e4afedf9e90f83c9a7f529
parentbd523af5fb49ec78073a35ce63d53ba5c32064d0 (diff)
downloadgba-renderers-53580f3695f6f53f2fc0ecea169609bc9d853643.tar.gz
gba-renderers-53580f3695f6f53f2fc0ecea169609bc9d853643.zip
Add new profiling macros
-rw-r--r--src/gba/gba.h4
-rw-r--r--src/main.c88
-rw-r--r--src/profiling.c140
-rw-r--r--src/renderer_m0.c2
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
419void 419void
420dma_copy(void *dst, const void *src, u32 size, int channel) { 420dma_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
426void 428void
427dma_fill(void *dst, vu32 src, u32 size, int channel) { 429dma_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//
diff --git a/src/main.c b/src/main.c
index 993ca37..14e04e9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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
54void 23void
55test_clear(void) { 24test_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
114void
115test_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
57static u32 prof_frame_counter = 0;
58
59static u32 frame_cycles = 0;
60static u32 flip_cycles = 0;
61static u32 clear_cycles = 0;
62static u32 line_cycles = 0;
63static u32 rect_cycles = 0;
64static u32 fill_rect_cycles = 0;
65static u32 chr_cycles = 0;
66static u32 icn_cycles = 0;
67
68static u32 avg_frame_cycles = 0;
69static u32 avg_flip_cycles = 0;
70static u32 avg_clear_cycles = 0;
71static u32 avg_line_cycles = 0;
72static u32 avg_rect_cycles = 0;
73static u32 avg_fill_rect_cycles = 0;
74static u32 avg_chr_cycles = 0;
75static 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.