@@ -69,10 +69,99 @@ namespace bgfx
6969 }
7070#endif // BGFX_CONFIG_USE_TINYSTL
7171
72+ struct Superluminal
73+ {
74+ struct SuppressTailCallOptimization
75+ {
76+ int64_t SuppressTailCall[3 ];
77+ };
78+
79+ typedef void (*SuperluminalBeginEventtFn)(const char * _inID, const char * _inData, uint32_t _inColor);
80+ typedef SuppressTailCallOptimization (*SuperluminalEndEventFn)();
81+
82+ static void stubSuperluminalBeginEvent (const char * _inID, const char * _inData, uint32_t _inColor)
83+ {
84+ BX_UNUSED (_inID, _inData, _inColor);
85+ }
86+
87+ static SuppressTailCallOptimization stubSuperluminalEndEvent ()
88+ {
89+ return {};
90+ }
91+
92+ bool init ()
93+ {
94+ if (!BX_ENABLED (BGFX_CONFIG_PROFILER) )
95+ {
96+ return false ;
97+ }
98+
99+ const char * superluminalDllName = " PerformanceAPI.dll" ;
100+ superluminalDll = bx::dlopen (superluminalDllName);
101+
102+ if (NULL != superluminalDll)
103+ {
104+ void * funcPtrs[11 ];
105+
106+ typedef int (*PerformanceAPI_GetAPI)(int32_t _version, void ** _funcPtrs);
107+
108+ constexpr int32_t version = 0x30000 ;
109+
110+ PerformanceAPI_GetAPI getApi = bx::dlsym<PerformanceAPI_GetAPI>(superluminalDll, " PerformanceAPI_GetAPI" );
111+ if (NULL == getApi)
112+ {
113+ BX_TRACE (" Failed to obtain Superluminal's %s GetAPI function!" , superluminalDllName);
114+ bx::dlclose (superluminalDll);
115+ return false ;
116+ }
117+
118+ if (getApi (version, funcPtrs) )
119+ {
120+ BX_TRACE (" Superluminal's PerformanceAPI.dll is loaded!" );
121+ beginEvent = (SuperluminalBeginEventtFn)funcPtrs[2 ];
122+ endEvent = (SuperluminalEndEventFn )funcPtrs[6 ];
123+ return true ;
124+ }
125+
126+ BX_TRACE (" Failed to obtain Superluminal's %s GetAPI function!" , superluminalDllName);
127+ bx::dlclose (superluminalDll);
128+ }
129+ else
130+ {
131+ BX_TRACE (" Failed to load Superluminal's %s!" , superluminalDllName);
132+ }
133+
134+ return false ;
135+ }
136+
137+ void shutdown ()
138+ {
139+ if (NULL != superluminalDll)
140+ {
141+ bx::dlclose (superluminalDll);
142+ superluminalDll = NULL ;
143+ beginEvent = stubSuperluminalBeginEvent;
144+ endEvent = stubSuperluminalEndEvent;
145+ }
146+ }
147+
148+ void * superluminalDll = NULL ;
149+ SuperluminalBeginEventtFn beginEvent = stubSuperluminalBeginEvent;
150+ SuperluminalEndEventFn endEvent = stubSuperluminalEndEvent;
151+ };
152+
72153 struct CallbackStub : public CallbackI
73154 {
155+ Superluminal m_superluminal;
156+
157+ CallbackStub ()
158+ {
159+ m_superluminal.init ();
160+ }
161+
74162 virtual ~CallbackStub ()
75163 {
164+ m_superluminal.shutdown ();
76165 }
77166
78167 virtual void fatal (const char * _filePath, uint16_t _line, Fatal::Enum _code, const char * _str) override
@@ -108,16 +197,19 @@ namespace bgfx
108197 bx::debugOutput (out);
109198 }
110199
111- virtual void profilerBegin (const char * /* _name*/ , uint32_t /* _abgr*/ , const char * /* _filePath*/ , uint16_t /* _line*/ ) override
200+ virtual void profilerBegin (const char * _name, uint32_t _abgr, const char * /* _filePath*/ , uint16_t /* _line*/ ) override
112201 {
202+ m_superluminal.beginEvent (" " , _name, _abgr);
113203 }
114204
115- virtual void profilerBeginLiteral (const char * /* _name*/ , uint32_t /* _abgr*/ , const char * /* _filePath*/ , uint16_t /* _line*/ ) override
205+ virtual void profilerBeginLiteral (const char * _name, uint32_t _abgr, const char * /* _filePath*/ , uint16_t /* _line*/ ) override
116206 {
207+ m_superluminal.beginEvent (_name, NULL , _abgr);
117208 }
118209
119210 virtual void profilerEnd () override
120211 {
212+ m_superluminal.endEvent ();
121213 }
122214
123215 virtual uint32_t cacheReadSize (uint64_t /* _id*/ ) override
0 commit comments