VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispProfile.h@ 34346

Last change on this file since 34346 was 32962, checked in by vboxsync, 14 years ago

wddm/3d: profiling

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/** @file
2 *
3 * VBoxVideo Display D3D User mode dll
4 *
5 * Copyright (C) 2010 Oracle Corporation
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 */
15#ifndef ___VBoxDispProfile_h__
16#define ___VBoxDispProfile_h__
17#include <iprt/ctype.h>
18#include <iprt/time.h>
19
20#include "VBoxDispD3DCmn.h"
21
22#define VBOXDISPPROFILE_MAX_SETSIZE 512
23#define VBOXDISPPROFILE_GET_TIME_NANO() RTTimeNanoTS()
24#define VBOXDISPPROFILE_GET_TIME_MILLI() RTTimeMilliTS()
25#define VBOXDISPPROFILE_DUMP(_m) do {\
26 vboxVDbgDoMpPrintF _m; \
27 } while (0)
28
29class VBoxDispProfileEntry
30{
31public:
32 VBoxDispProfileEntry() :
33 m_cCalls(0),
34 m_cTime(0),
35 m_pName(NULL)
36 {}
37
38 VBoxDispProfileEntry(const char *pName) :
39 m_cCalls(0),
40 m_cTime(0),
41 m_pName(pName)
42 {}
43
44 void step(uint64_t cTime)
45 {
46 ++m_cCalls;
47 m_cTime+= cTime;
48 }
49
50 void reset()
51 {
52 m_cCalls = 0;
53 m_cTime = 0;
54 }
55
56 void dump(const PVBOXWDDMDISP_DEVICE pDevice) const
57 {
58// VBOXDISPPROFILE_DUMP((pDevice, "Entry '%s': calls(%d), time: nanos(%I64u), micros(%I64u), millis(%I64u)\n",
59// m_pName, m_cCalls,
60// m_cTime, m_cTime/1000, m_cTime/1000000));
61 VBOXDISPPROFILE_DUMP((pDevice, "%s\t%d\t%I64u\t%I64u\t%I64u\n",
62 m_pName, m_cCalls,
63 m_cTime, m_cTime/1000, m_cTime/1000000));
64 }
65private:
66 uint32_t m_cCalls;
67 uint64_t m_cTime;
68 const char * m_pName;
69};
70
71class VBoxDispProfileSet
72{
73public:
74 VBoxDispProfileSet(const char *pName) :
75 m_cEntries(0),
76 m_pName(pName)
77 {}
78
79 VBoxDispProfileEntry * alloc(const char *pName)
80 {
81 if (m_cEntries < RT_ELEMENTS(m_Entries))
82 {
83 VBoxDispProfileEntry * entry = &m_Entries[m_cEntries];
84 ++m_cEntries;
85 *entry = VBoxDispProfileEntry(pName);
86 return entry;
87 }
88 return NULL;
89 }
90
91 void resetEntries()
92 {
93 for (uint32_t i = 0; i < m_cEntries; ++i)
94 {
95 m_Entries[i].reset();
96 }
97 }
98
99 void dump(const PVBOXWDDMDISP_DEVICE pDevice)
100 {
101 VBOXDISPPROFILE_DUMP((pDevice, ">>>> Start of VBox Disp Dump '%s': num entries(%d) >>>>>\n", m_pName, m_cEntries));
102 VBOXDISPPROFILE_DUMP((pDevice, "Name\tCalls\tNanos\tMicros\tMillis\n"));
103 for (uint32_t i = 0; i < m_cEntries; ++i)
104 {
105 m_Entries[i].dump(pDevice);
106 }
107 VBOXDISPPROFILE_DUMP((pDevice, "<<<< Endi of VBox Disp Dump '%s' <<<<<\n", m_pName));
108 }
109
110private:
111 VBoxDispProfileEntry m_Entries[VBOXDISPPROFILE_MAX_SETSIZE];
112 uint32_t m_cEntries;
113 const char * m_pName;
114};
115
116template<typename T> class VBoxDispProfileScopeLogger
117{
118public:
119 VBoxDispProfileScopeLogger(T *pEntry) :
120 m_pEntry(pEntry),
121 m_bDisable(FALSE)
122 {
123 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
124 }
125
126 ~VBoxDispProfileScopeLogger()
127 {
128 if (!m_bDisable)
129 {
130 logStep();
131 }
132 }
133
134 void disable()
135 {
136 m_bDisable = TRUE;
137 }
138
139 void logAndDisable()
140 {
141 logStep();
142 disable();
143 }
144
145private:
146 void logStep()
147 {
148 uint64_t cNewTime = VBOXDISPPROFILE_GET_TIME_NANO();
149 m_pEntry->step(cNewTime - m_cTime);
150 }
151 T *m_pEntry;
152 uint64_t m_cTime;
153 BOOL m_bDisable;
154};
155
156
157class VBoxDispProfileFpsCounter
158{
159public:
160 VBoxDispProfileFpsCounter(uint32_t cPeriods)
161 {
162 memset(&m_Data, 0, sizeof (m_Data));
163 m_Data.mcPeriods = cPeriods;
164 m_Data.mpaPeriods = (uint64_t *)RTMemAllocZ(sizeof (m_Data.mpaPeriods[0]) * cPeriods);
165 m_Data.mpaCalls = (uint32_t *)RTMemAllocZ(sizeof (m_Data.mpaCalls[0]) * cPeriods);
166 m_Data.mpaTimes = (uint64_t *)RTMemAllocZ(sizeof (m_Data.mpaTimes[0]) * cPeriods);
167 }
168
169 ~VBoxDispProfileFpsCounter()
170 {
171 RTMemFree(m_Data.mpaPeriods);
172 RTMemFree(m_Data.mpaCalls);
173 RTMemFree(m_Data.mpaTimes);
174 }
175
176 void ReportFrame()
177 {
178 uint64_t cur = VBOXDISPPROFILE_GET_TIME_NANO();
179
180 if(m_Data.mPrevTime)
181 {
182 uint64_t curPeriod = cur - m_Data.mPrevTime;
183
184 m_Data.mPeriodSum += curPeriod - m_Data.mpaPeriods[m_Data.miPeriod];
185 m_Data.mpaPeriods[m_Data.miPeriod] = curPeriod;
186
187 m_Data.mCallsSum += m_Data.mCurCalls - m_Data.mpaCalls[m_Data.miPeriod];
188 m_Data.mpaCalls[m_Data.miPeriod] = m_Data.mCurCalls;
189
190 m_Data.mTimeUsedSum += m_Data.mCurTimeUsed - m_Data.mpaTimes[m_Data.miPeriod];
191 m_Data.mpaTimes[m_Data.miPeriod] = m_Data.mCurTimeUsed;
192
193 ++m_Data.miPeriod;
194 m_Data.miPeriod %= m_Data.mcPeriods;
195 }
196 m_Data.mPrevTime = cur;
197 ++m_Data.mcFrames;
198
199 m_Data.mCurTimeUsed = 0;
200 m_Data.mCurCalls = 0;
201 }
202
203 void step(uint64_t Time)
204 {
205 m_Data.mCurTimeUsed += Time;
206 ++m_Data.mCurCalls;
207 }
208
209 uint64_t GetEveragePeriod()
210 {
211 return m_Data.mPeriodSum / m_Data.mcPeriods;
212 }
213
214 double GetFps()
215 {
216 return ((double)1000000000.0) / GetEveragePeriod();
217 }
218
219 double GetCps()
220 {
221 return GetFps() * m_Data.mCallsSum / m_Data.mcPeriods;
222 }
223
224 double GetTimeProcPercent()
225 {
226 return 100.0*m_Data.mTimeUsedSum/m_Data.mPeriodSum;
227 }
228
229 uint64_t GetNumFrames()
230 {
231 return m_Data.mcFrames;
232 }
233private:
234 struct
235 {
236 uint64_t mPeriodSum;
237 uint64_t *mpaPeriods;
238 uint64_t mPrevTime;
239 uint64_t mcFrames;
240 uint32_t mcPeriods;
241 uint32_t miPeriod;
242
243 uint64_t mCallsSum;
244 uint32_t *mpaCalls;
245
246 uint64_t mTimeUsedSum;
247 uint64_t *mpaTimes;
248
249 uint64_t mCurTimeUsed;
250 uint64_t mCurCalls;
251 } m_Data;
252};
253
254#define VBOXDISPPROFILE_FUNCTION_LOGGER_DISABLE_CURRENT() do { \
255 __vboxDispProfileFunctionLogger.disable();\
256 } while (0)
257
258#define VBOXDISPPROFILE_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() do { \
259 __vboxDispProfileFunctionLogger.logAndDisable();\
260 } while (0)
261
262#define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p) \
263 static VBoxDispProfileEntry * __pVBoxDispProfileEntry = NULL; \
264 if (!__pVBoxDispProfileEntry) { __pVBoxDispProfileEntry = _p.alloc(__FUNCTION__); } \
265 VBoxDispProfileScopeLogger<VBoxDispProfileEntry> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry);
266
267#define VBOXDISPPROFILE_STATISTIC_LOGGER_DISABLE_CURRENT() do { \
268 __vboxDispProfileStatisticLogger.disable();\
269 } while (0)
270
271#define VBOXDISPPROFILE_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT() do { \
272 __vboxDispProfileStatisticLogger.logAndDisable();\
273 } while (0)
274
275
276#define VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(_p) \
277 VBoxDispProfileScopeLogger<VBoxDispProfileFpsCounter> __vboxDispProfileStatisticLogger(_p);
278
279//#define VBOXDISPPROFILE_FUNCTION_PROLOGUE(_p) \
280// VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p)
281
282#endif /* #ifndef ___VBoxDispProfile_h__ */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette