summaryrefslogtreecommitdiff
path: root/Runtime/Profiler/Profiler.h
blob: ee47e6c846d4ca02cc8c734405105be8c0d5cae0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#ifndef _PROFILER_H_
#define _PROFILER_H_

#include "Configuration/UnityConfigure.h"

#if ENABLE_PROFILER

#include "Runtime/Utilities/EnumFlags.h"
#include "Runtime/Scripting/Backend/ScriptingTypes.h"

/*
 // Example of profiling a code block:
 // Define PROFILER_INFORMATION outside of a function
 
 PROFILER_INFORMATION (gMyReallyFastFunctionProfile, "MyClass.MyFunction", kProfilerRender)
 
 void MyFunction ()
 {
 PROFILER_AUTO (gMyReallyFastFunctionProfile, this or NULL);
 // or
 PROFILER_BEGIN (gMyReallyFastFunctionProfile, this or NULL);
 PROFILER_END
 }
 
 // PROFILER_AUTO_THREAD_SAFE etc. can be used if you are not sure if the code might be called from another thread
 // PROFILER_AUTO_INTERNAL etc. can be used if you do not want the profiler blocks to be in released 
 //                         unity builds only in internal developer builds
 
 */

enum ProfilerMode 
{
	kProfilerEnabled = 1 << 0, 
	kProfilerGame = 1 << 1, 
	kProfilerDeepScripts = 1 << 2, 
	kProfilerEditor = 1 << 3, 
};
ENUM_FLAGS(ProfilerMode);

class Object;
struct ProfilerSample;

// ProfilerHistory uses AddToChart to sum the different groups into different charts.
// Only kProfilerRender, kProfilerScripts, kProfilerPhysics, kProfilerGC, kProfilerVSync currently make any impact in the UI.
enum ProfilerGroup
{
	kProfilerRender,
	kProfilerScripts,
	kProfilerGUI,
	kProfilerPhysics,	
	kProfilerAnimation,
	kProfilerAI,
	kProfilerAudio,
	kProfilerParticles,
	kProfilerNetwork,
	kProfilerLoading,
	kProfilerOther,
	kProfilerGC,
	kProfilerVSync,
	kProfilerOverhead,
	kProfilerPlayerLoop,
	kProfilerGroupCount
};

enum GpuSection
{
	kGPUSectionOther,
	kGPUSectionOpaquePass,
	kGPUSectionTransparentPass,
	kGPUSectionShadowPass,
	kGPUSectionDeferedPrePass,
	kGPUSectionDeferedLighting,
	kGPUSectionPostProcess
};

struct EXPORT_COREMODULE ProfilerInformation
{
	ProfilerInformation (const char* const functionName, ProfilerGroup grp, bool warn = false );
	
	const char* name; // function
	UInt16 group; // ProfilerGroup
	enum { kDefault = 0, kScriptMonoRuntimeInvoke = 1, kScriptEnterLeave = 2 };
	UInt8 flags;
	UInt8 isWarning;

	void* intelGPAData;
};

void EXPORT_COREMODULE profiler_begin(ProfilerInformation* info, const Object* obj);
void EXPORT_COREMODULE profiler_end();

void EXPORT_COREMODULE profiler_begin_thread_safe(ProfilerInformation* info, const Object* obj);
void EXPORT_COREMODULE profiler_end_thread_safe();

ProfilerSample* EXPORT_COREMODULE mono_profiler_begin(ScriptingMethodPtr method, ScriptingClassPtr profileKlass, ScriptingObjectPtr instance);
void EXPORT_COREMODULE mono_profiler_end(ProfilerSample* beginsample);

void EXPORT_COREMODULE gpu_time_sample();

void profiler_begin_frame();
void profiler_end_frame();
void profiler_start_mode(ProfilerMode flags);
void profiler_end_mode(ProfilerMode flags);

// Create&destroy a profiler for a specific thread (Used by worker threads & GPU thread)
void profiler_initialize_thread (const char* name, bool separateBeginEnd);
void profiler_cleanup_thread ();

// API for worker threads & GfxThread
void profiler_set_active_seperate_thread (bool enabled);
void profiler_begin_frame_seperate_thread (ProfilerMode mode);
void profiler_end_frame_seperate_thread (int frameIDAndValid);
void profiler_disable_sampling_seperate_thread ();

// Profiler interface macros
#define PROFILER_INFORMATION(VAR_NAME, NAME, GROUP) static ProfilerInformation VAR_NAME(NAME, GROUP);
#define PROFILER_WARNING(VAR_NAME, NAME, GROUP) static ProfilerInformation VAR_NAME(NAME, GROUP, true);
#define PROFILER_AUTO(INFO, OBJECT_PTR) ProfilerAutoObject _PROFILER_AUTO_OBJECT_(&INFO, OBJECT_PTR);
#define PROFILER_BEGIN(INFO, OBJECT_PTR) profiler_begin (&INFO, OBJECT_PTR);
#define PROFILER_END profiler_end();

#define MONO_PROFILER_BEGIN(monomethod,monoclass,obj) ProfilerSample* beginsample = mono_profiler_begin (monomethod, monoclass,obj);
#define MONO_PROFILER_END mono_profiler_end(beginsample);

#define PROFILER_AUTO_THREAD_SAFE(INFO, OBJECT_PTR) ProfilerAutoObjectThreadSafe _PROFILER_AUTO_OBJECT_(&INFO, OBJECT_PTR);

#define GPU_TIMESTAMP() gpu_time_sample(); 
#define GPU_AUTO_SECTION(section) AutoGpuSection autoGpuSection(section);

struct ProfilerAutoObject
{
	ProfilerAutoObject (ProfilerInformation* info, const Object* obj) { profiler_begin(info, obj); }
	~ProfilerAutoObject() { profiler_end(); }
};

struct ProfilerAutoObjectThreadSafe
{
	ProfilerAutoObjectThreadSafe (ProfilerInformation* info, const Object* obj) { profiler_begin_thread_safe (info, obj); }
	~ProfilerAutoObjectThreadSafe() { profiler_end_thread_safe(); }
};

extern GpuSection g_CurrentGPUSection;

class AutoGpuSection
{
public:
	AutoGpuSection(GpuSection section) { oldGPUSection = g_CurrentGPUSection; g_CurrentGPUSection = section; }
	~AutoGpuSection() { g_CurrentGPUSection = oldGPUSection; }
private:
	GpuSection oldGPUSection;
};


#else

#define PROFILER_INFORMATION(VAR_NAME, NAME, GROUP)
#define PROFILER_WARNING(VAR_NAME, NAME, GROUP)
#define PROFILER_AUTO(INFO, OBJECT_PTR) 
#define PROFILER_BEGIN(INFO, OBJECT_PTR) 
#define PROFILER_END 
#define MONO_PROFILER_BEGIN(monomethod,monoclass,obj)
#define MONO_PROFILER_END

#define PROFILER_AUTO_THREAD_SAFE(INFO, OBJECT_PTR) 

#define GPU_TIMESTAMP() 
#define GPU_AUTO_SECTION(section)


#endif


#if ENABLE_PROFILER_INTERNAL_CALLS
#define PROFILER_AUTO_INTERNAL(INFO, OBJECT_PTR) PROFILER_AUTO(INFO, OBJECT_PTR)
#define PROFILER_BEGIN_INTERNAL(INFO, OBJECT_PTR) PROFILER_BEGIN(INFO, OBJECT_PTR)
#define PROFILER_END_INTERNAL PROFILER_END

#define PROFILER_AUTO_THREAD_SAFE_INTERNAL(INFO, OBJECT_PTR) PROFILER_AUTO_THREAD_SAFE(INFO, OBJECT_PTR)
#else
#define PROFILER_AUTO_INTERNAL(INFO, OBJECT_PTR) 
#define PROFILER_BEGIN_INTERNAL(INFO, OBJECT_PTR) 
#define PROFILER_END_INTERNAL 

#define PROFILER_AUTO_THREAD_SAFE_INTERNAL(INFO, OBJECT_PTR) 
#endif

#endif /*_PROFILER_H_*/