/[pcsx2_0.9.7]/trunk/plugins/zzogl-pg/opengl/Profile.cpp
ViewVC logotype

Contents of /trunk/plugins/zzogl-pg/opengl/Profile.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 1 month ago) by william
File size: 6362 byte(s)
re-commit (had local access denied errors when committing)
1 /* ZZ Open GL graphics plugin
2 * Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
3 * Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20
21 ////////////////////
22 // Small profiler //
23 ////////////////////
24 #include <list>
25 #include <string>
26 #include <map>
27 #include "Profile.h"
28 #include "Util.h"
29
30 using namespace std;
31
32 #define GET_PROFILE_TIME() GetCPUTicks()
33
34 #if !defined(ZEROGS_DEVBUILD)
35 #define g_bWriteProfile 0
36 #else
37 bool g_bWriteProfile = 0;
38 #endif
39
40 u64 luPerfFreq;
41
42 struct DVPROFSTRUCT;
43
44 struct DVPROFSTRUCT
45 {
46
47 struct DATA
48 {
49 DATA(u64 time, u32 user = 0) : dwTime(time), dwUserData(user) {}
50
51 DATA() : dwTime(0), dwUserData(0) {}
52
53 u64 dwTime;
54 u32 dwUserData;
55 };
56
57 ~DVPROFSTRUCT()
58 {
59 list<DVPROFSTRUCT*>::iterator it = listpChild.begin();
60
61 while (it != listpChild.end())
62 {
63 safe_delete(*it);
64 ++it;
65 }
66 }
67
68 list<DATA> listTimes; // before DVProfEnd is called, contains the global time it started
69 // after DVProfEnd is called, contains the time it lasted
70 // the list contains all the tracked times
71 char pname[256];
72
73 list<DVPROFSTRUCT*> listpChild; // other profilers called during this profiler period
74 };
75
76 struct DVPROFTRACK
77 {
78 u32 dwUserData;
79 DVPROFSTRUCT::DATA* pdwTime;
80 DVPROFSTRUCT* pprof;
81 };
82
83 list<DVPROFTRACK> g_listCurTracking; // the current profiling functions, the back element is the
84 // one that will first get popped off the list when DVProfEnd is called
85 // the pointer is an element in DVPROFSTRUCT::listTimes
86 list<DVPROFSTRUCT> g_listProfilers; // the current profilers, note that these are the parents
87 // any profiler started during the time of another is held in
88 // DVPROFSTRUCT::listpChild
89 list<DVPROFSTRUCT*> g_listAllProfilers; // ignores the hierarchy, pointer to elements in g_listProfilers
90
91 void DVProfRegister(char* pname)
92 {
93 if (!g_bWriteProfile) return;
94
95 list<DVPROFSTRUCT*>::iterator it = g_listAllProfilers.begin();
96
97 // while(it != g_listAllProfilers.end() ) {
98 //
99 // if( _tcscmp(pname, (*it)->pname) == 0 ) {
100 // (*it)->listTimes.push_back(timeGetTime());
101 // DVPROFTRACK dvtrack;
102 // dvtrack.pdwTime = &(*it)->listTimes.back();
103 // dvtrack.pprof = *it;
104 // g_listCurTracking.push_back(dvtrack);
105 // return;
106 // }
107 //
108 // ++it;
109 // }
110
111 // else add in a new profiler to the appropriate parent profiler
112 DVPROFSTRUCT* pprof = NULL;
113
114 if (g_listCurTracking.size() > 0)
115 {
116 assert(g_listCurTracking.back().pprof != NULL);
117 g_listCurTracking.back().pprof->listpChild.push_back(new DVPROFSTRUCT());
118 pprof = g_listCurTracking.back().pprof->listpChild.back();
119 }
120 else
121 {
122 g_listProfilers.push_back(DVPROFSTRUCT());
123 pprof = &g_listProfilers.back();
124 }
125
126 strncpy(pprof->pname, pname, 256);
127
128 // setup the profiler for tracking
129 pprof->listTimes.push_back(DVPROFSTRUCT::DATA(GET_PROFILE_TIME()));
130
131 DVPROFTRACK dvtrack;
132 dvtrack.pdwTime = &pprof->listTimes.back();
133 dvtrack.pprof = pprof;
134 dvtrack.dwUserData = 0;
135
136 g_listCurTracking.push_back(dvtrack);
137
138 // add to all profiler list
139 g_listAllProfilers.push_back(pprof);
140 }
141
142 void DVProfEnd(u32 dwUserData)
143 {
144 if (!g_bWriteProfile)
145 return;
146
147 B_RETURN(g_listCurTracking.size() > 0);
148
149 DVPROFTRACK dvtrack = g_listCurTracking.back();
150
151 assert(dvtrack.pdwTime != NULL && dvtrack.pprof != NULL);
152
153 dvtrack.pdwTime->dwTime = 1000000 * (GET_PROFILE_TIME() - dvtrack.pdwTime->dwTime) / luPerfFreq;
154
155 dvtrack.pdwTime->dwUserData = dwUserData;
156
157 g_listCurTracking.pop_back();
158 }
159
160 struct DVTIMEINFO
161 {
162 DVTIMEINFO() : uInclusive(0), uExclusive(0) {}
163
164 u64 uInclusive, uExclusive;
165 };
166
167 map<string, DVTIMEINFO> mapAggregateTimes;
168
169 u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident)
170 {
171 fprintf(f, "%*s%s - ", ident, "", p->pname);
172
173 list<DVPROFSTRUCT::DATA>::iterator ittime = p->listTimes.begin();
174
175 u64 utime = 0;
176
177 while (ittime != p->listTimes.end())
178 {
179 utime += (u32)ittime->dwTime;
180
181 if (ittime->dwUserData)
182 fprintf(f, "time: %d, user: 0x%8.8x", (u32)ittime->dwTime, ittime->dwUserData);
183 else
184 fprintf(f, "time: %d", (u32)ittime->dwTime);
185
186 ++ittime;
187 }
188
189 mapAggregateTimes[p->pname].uInclusive += utime;
190
191 fprintf(f, "\n");
192
193 list<DVPROFSTRUCT*>::iterator itprof = p->listpChild.begin();
194
195 u32 uex = utime;
196
197 while (itprof != p->listpChild.end())
198 {
199
200 uex -= (u32)DVProfWriteStruct(f, *itprof, ident + 4);
201 ++itprof;
202 }
203
204 mapAggregateTimes[p->pname].uExclusive += uex;
205
206 return utime;
207 }
208
209 void DVProfWrite(char* pfilename, u32 frames)
210 {
211 assert(pfilename != NULL);
212 FILE* f = fopen(pfilename, "wb");
213
214 mapAggregateTimes.clear();
215 list<DVPROFSTRUCT>::iterator it = g_listProfilers.begin();
216
217 while (it != g_listProfilers.end())
218 {
219 DVProfWriteStruct(f, &(*it), 0);
220 ++it;
221 }
222
223 {
224 map<string, DVTIMEINFO>::iterator it;
225 fprintf(f, "\n\n-------------------------------------------------------------------\n\n");
226
227 u64 uTotal[2] = {0};
228 double fiTotalTime[2];
229
230 for (it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it)
231 {
232 uTotal[0] += it->second.uExclusive;
233 uTotal[1] += it->second.uInclusive;
234 }
235
236 fprintf(f, "total times (%d): ex: %Lu ", frames, uTotal[0] / frames);
237
238 fprintf(f, "inc: %Lu\n", uTotal[1] / frames);
239
240 fiTotalTime[0] = 1.0 / (double)uTotal[0];
241 fiTotalTime[1] = 1.0 / (double)uTotal[1];
242
243 // output the combined times
244
245 for (it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it)
246 {
247 fprintf(f, "%s - ex: %f inc: %f\n", it->first.c_str(), (double)it->second.uExclusive * fiTotalTime[0],
248 (double)it->second.uInclusive * fiTotalTime[1]);
249 }
250 }
251
252
253 fclose(f);
254 }
255
256 void DVProfClear()
257 {
258 g_listCurTracking.clear();
259 g_listProfilers.clear();
260 g_listAllProfilers.clear();
261 }
262
263 void InitProfile()
264 {
265 luPerfFreq = GetCPUTicks();
266 }

  ViewVC Help
Powered by ViewVC 1.1.22