Jo Engine 2026.11.1
Jo Sega Saturn Engine
Loading...
Searching...
No Matches
profile.h
Go to the documentation of this file.
1/*
2** Jo Sega Saturn Engine
3** Copyright (c) 2012-2026, Johannes Fetz (johannesfetz@gmail.com)
4** All rights reserved.
5**
6** Redistribution and use in source and binary forms, with or without
7** modification, are permitted provided that the following conditions are met:
8** * Redistributions of source code must retain the above copyright
9** notice, this list of conditions and the following disclaimer.
10** * Redistributions in binary form must reproduce the above copyright
11** notice, this list of conditions and the following disclaimer in the
12** documentation and/or other materials provided with the distribution.
13** * Neither the name of the Johannes Fetz nor the
14** names of its contributors may be used to endorse or promote products
15** derived from this software without specific prior written permission.
16**
17** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20** DISCLAIMED. IN NO EVENT SHALL Johannes Fetz BE LIABLE FOR ANY
21** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
51
52#ifndef __JO_PROFILE_H__
53# define __JO_PROFILE_H__
54
103
107# define JO_PROFILE_USER(N) ((jo_profile_slot)(JO_PROFILE_FIRST_USER + (N)))
108
110# define JO_PROFILE_FRAMES (32)
111
112#ifdef JO_COMPILE_WITH_PROFILER_SUPPORT
113
115typedef struct
116{
117 unsigned int sum[JO_PROFILE_COUNT]; // Never reset (the differences are computed)
118 unsigned int max[JO_PROFILE_COUNT];
119 unsigned short start[JO_PROFILE_COUNT]; // See jo_profile_begin()
120} jo_profile_cpu;
121
123extern jo_profile_cpu __jo_profile_cpu[2];
124
128static __jo_force_inline unsigned int jo_profile_ticks(void)
129{
130 unsigned int high;
131
132 // The high byte must be read first (the low byte is latched)
133 high = *(volatile unsigned char *)0xFFFFFE12;
134 return ((high << 8) | *(volatile unsigned char *)0xFFFFFE13);
135}
136
143static __jo_force_inline jo_profile_cpu *__jo_profile_current_cpu(void)
144{
145 unsigned int sp;
146
147 __asm__ volatile ("mov r15, %0" : "=r" (sp));
148 return (&__jo_profile_cpu[(sp & 0x000FFFFF) < 0x4000 ? 1 : 0]);
149}
150
154static __jo_force_inline void __jo_profile_add(jo_profile_cpu * const cpu, const jo_profile_slot slot, const unsigned int value)
155{
156 // (through the cache: a read without the cache cost about 10 cycles for each measure, several per object drawn)
157 cpu->sum[slot] += value;
158 if (value > cpu->max[slot])
159 cpu->max[slot] = value;
160}
161
167{
168 __jo_profile_current_cpu()->start[slot] = (unsigned short)jo_profile_ticks();
169}
170
176{
177 jo_profile_cpu *cpu;
178
179 cpu = __jo_profile_current_cpu();
180 __jo_profile_add(cpu, slot, (jo_profile_ticks() - cpu->start[slot]) & 0xFFFF);
181}
182
187static __jo_force_inline void jo_profile_count(const jo_profile_slot slot, const unsigned int value)
188{
189 __jo_profile_add(__jo_profile_current_cpu(), slot, value);
190}
191
199bool jo_profile_get(const jo_profile_slot slot, unsigned int *average, unsigned int *maximum);
200
204void jo_profile_count_pixels(const bool enabled);
206extern bool __jo_profile_pixels;
207
212void jo_profile_set_name(const jo_profile_slot slot, const char * const name);
213
220void jo_profile_print(const int x, const int y);
221
223# define JO_PROFILE_SAMPLING_CODE_START (0x06004000)
225# define JO_PROFILE_SAMPLING_BIN_SIZE (16)
227# define JO_PROFILE_SAMPLING_BINS (16384)
228
237void jo_profile_sampling_start(unsigned int *master_histogram, unsigned int *slave_histogram);
238
241void __jo_profile_slave_job(void);
242
244void __jo_profile_init(void);
245
247void __jo_profile_end_frame(void);
248
250void __jo_profile_vdp1_start(void);
251
252#else
253
254# define jo_profile_begin(SLOT) do {} while (0)
255# define jo_profile_end(SLOT) do {} while (0)
256# define jo_profile_count(SLOT, VALUE) do {} while (0)
257# define jo_profile_set_name(SLOT, NAME) do {} while (0)
258# define jo_profile_print(X, Y) do {} while (0)
259# define jo_profile_count_pixels(ENABLED) do {} while (0)
260# define jo_profile_sampling_start(M, S) do {} while (0)
261# define __jo_profile_slave_job() do {} while (0)
262
263#endif /* !JO_COMPILE_WITH_PROFILER_SUPPORT */
264
265#endif /* !__JO_PROFILE_H__ */
266
267/*
268** END OF FILE
269*/
#define jo_profile_print(X, Y)
Definition profile.h:258
#define jo_profile_begin(SLOT)
Definition profile.h:254
#define jo_profile_sampling_start(M, S)
Definition profile.h:260
#define jo_profile_end(SLOT)
Definition profile.h:255
jo_profile_slot
Measures of the engine and of the program (jo_profile_begin(), jo_profile_end(), jo_profile_count()).
Definition profile.h:57
@ JO_PROFILE_3D_VERTEX_COUNT
3D vertices transformed per frame (count, both CPUs)
Definition profile.h:85
@ JO_PROFILE_3D_VERTICES
3D: transformation and projection of the vertices (both CPUs)
Definition profile.h:87
@ JO_PROFILE_CALLBACKS
Callbacks of the master CPU (jo_core_add_callback()).
Definition profile.h:61
@ JO_PROFILE_VDP1_DRAW
VDP1: from the display of a new command table to the end of its drawing.
Definition profile.h:75
@ JO_PROFILE_VBLANKS
VBLANK per frame (count, x 100).
Definition profile.h:77
@ JO_PROFILE_FIRST_USER
First measure of the program (see JO_PROFILE_USER()).
Definition profile.h:99
@ JO_PROFILE_VDP1_COPY
Copy of the VDP1 commands of a frame into the VDP1 VRAM.
Definition profile.h:69
@ JO_PROFILE_3D_LIGHT
3D: lighting of the polygons (JO_3D_USE_LIGHT), both CPUs (included in JO_PROFILE_3D_POLYGONS)
Definition profile.h:93
@ JO_PROFILE_COUNT
Measures count.
Definition profile.h:101
@ JO_PROFILE_3D_POLYGON_COUNT
3D polygons tested per frame, visible or not (count, both CPUs)
Definition profile.h:83
@ JO_PROFILE_VDP1_COMMANDS
VDP1 commands per frame (count).
Definition profile.h:79
@ JO_PROFILE_SLAVE
Slave CPU busy (all its jobs: the callbacks of jo_core_exec_on_slave() and the engine jobs).
Definition profile.h:65
@ JO_PROFILE_VDP1_WAIT
Wait for the VDP1 before the copy (previous table not displayed yet, or still drawn).
Definition profile.h:71
@ JO_PROFILE_FRAME
Frame: from the start of the callbacks of a frame to the start of the next one.
Definition profile.h:59
@ JO_PROFILE_VDP1_SORT
Sort of the VDP1 commands of a frame.
Definition profile.h:67
@ JO_PROFILE_3D_PIXELS
3D: estimate of the pixels the VDP1 draws for the polygons of a frame (count, both CPUs): the VDP1 dr...
Definition profile.h:97
@ JO_PROFILE_VSYNC
Master CPU waiting for the VBLANK at the end of the frame (JO_FRAMERATE).
Definition profile.h:73
@ JO_PROFILE_POLYGONS
3D polygons displayed per frame (count)
Definition profile.h:81
@ JO_PROFILE_3D_CLIP
3D: polygons near the camera (subdivided) or crossing the near plane (clipped), both CPUs (included i...
Definition profile.h:91
@ JO_PROFILE_WAIT_SLAVE
Master CPU waiting for the slave CPU (jo_core_wait_for_slave()).
Definition profile.h:63
@ JO_PROFILE_3D_POLYGONS
3D: polygons (visibility, clipping, lighting, VDP1 commands), both CPUs
Definition profile.h:89
#define jo_profile_set_name(SLOT, NAME)
Definition profile.h:257
#define jo_profile_count(SLOT, VALUE)
Definition profile.h:256
#define __jo_profile_slave_job()
Definition profile.h:261
#define jo_profile_count_pixels(ENABLED)
Definition profile.h:259
#define __jo_force_inline
force inline attribute (and prevent Doxygen prototype parsing bug)
Definition types.h:39