1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "stddirect3d.h"
19 #include "driver_direct3d.h"
20 #include "nel/misc/hierarchical_timer.h"
27 using namespace NLMISC
;
32 // ***************************************************************************
34 void CDriverD3D::profileRenderedPrimitives(CPrimitiveProfile
&pIn
, CPrimitiveProfile
&pOut
)
36 pIn
= _PrimitiveProfileIn
;
37 pOut
= _PrimitiveProfileOut
;
40 // ***************************************************************************
42 uint32
CDriverD3D::profileAllocatedTextureMemory()
44 return _AllocatedTextureMemory
;
47 // ***************************************************************************
49 uint32
CDriverD3D::profileSetupedMaterials() const
51 return _NbSetupMaterialCall
;
54 // ***************************************************************************
56 uint32
CDriverD3D::profileSetupedModelMatrix() const
58 return _NbSetupModelMatrixCall
;
61 // ***************************************************************************
63 void CDriverD3D::enableUsedTextureMemorySum (bool enable
)
66 nlinfo ("PERFORMANCE INFO: enableUsedTextureMemorySum has been set to true in CDriverD3D\n");
67 _SumTextureMemoryUsed
=enable
;
70 // ***************************************************************************
72 uint32
CDriverD3D::getUsedTextureMemory() const
77 // For each texture used
78 set
<CTextureDrvInfosD3D
*>::const_iterator ite
=_TextureUsed
.begin();
79 while (ite
!=_TextureUsed
.end())
81 // Get the d3d texture
82 CTextureDrvInfosD3D
* d3dtext
;
85 // Sum the memory used by this texture
86 memory
+=d3dtext
->TextureMemory
;
96 // ***************************************************************************
97 void CDriverD3D::startProfileVBHardLock()
103 _VBHardProfiles
.clear();
104 _VBHardProfiles
.reserve(50);
105 _VBHardProfiling
= true;
106 _CurVBHardLockCount
= 0;
107 _NumVBHardProfileFrame
= 0;
108 _VolatileVBLockTime
= 0;
111 // ***************************************************************************
113 void CDriverD3D::endProfileVBHardLock(std::vector
<std::string
> &result
)
115 if(!_VBHardProfiling
)
120 result
.resize(_VBHardProfiles
.size() + 2);
122 for(uint i
=0;i
<_VBHardProfiles
.size();i
++)
124 const uint tmpSize
= 256;
126 CVBHardProfile
&vbProf
= _VBHardProfiles
[i
];
128 if(vbProf
.VBHard
&& !vbProf
.VBHard
->getName().empty())
130 vbName
= vbProf
.VBHard
->getName().c_str();
137 float timeLock
= (float)CTime::ticksToSecond(vbProf
.AccumTime
)*1000 / max(_NumVBHardProfileFrame
,1U);
138 smprintf(tmp
, tmpSize
, "%16s%c: %2.3f ms", vbName
, vbProf
.Change
?'*':' ', timeLock
);
143 result
[_VBHardProfiles
.size()]= toString("Total: %2.3f", total
);
144 // float volatileVBTimeLock = (float)CTime::ticksToSecond(_VolatileVBLockTime)*1000 / max(_NumVBHardProfileFrame,1U);
145 result
[_VBHardProfiles
.size() + 1]= toString("Volatile Vertex Buffer lock time = %2.3f", _VolatileVBLockTime
);
148 _VBHardProfiling
= false;
149 contReset(_VBHardProfiles
);
152 // ***************************************************************************
154 void CDriverD3D::appendVBHardLockProfile(NLMISC::TTicks time
, CVertexBuffer
*vb
)
156 // must allocate a new place?
157 if(_CurVBHardLockCount
>=_VBHardProfiles
.size())
159 _VBHardProfiles
.resize(_VBHardProfiles
.size()+1);
160 // set the original VBHard
161 _VBHardProfiles
[_CurVBHardLockCount
].VBHard
= vb
;
165 _VBHardProfiles
[_CurVBHardLockCount
].AccumTime
+= time
;
166 // if change of VBHard for this chrono place
167 if(_VBHardProfiles
[_CurVBHardLockCount
].VBHard
!= vb
)
170 _VBHardProfiles
[_CurVBHardLockCount
].VBHard
= vb
;
171 _VBHardProfiles
[_CurVBHardLockCount
].Change
= true;
175 _CurVBHardLockCount
++;
178 // ***************************************************************************
179 void CDriverD3D::startProfileIBLock()
186 _IBProfiles
.reserve(50);
189 _NumIBProfileFrame
= 0;
190 _VolatileIBLockTime
= 0;
193 // ***************************************************************************
195 void CDriverD3D::endProfileIBLock(std::vector
<std::string
> &result
)
202 result
.resize(_IBProfiles
.size() + 2);
204 for(uint i
=0;i
<_IBProfiles
.size();i
++)
206 const uint tmpSize
= 256;
208 CIBProfile
&ibProf
= _IBProfiles
[i
];
210 if(ibProf
.IB
&& !ibProf
.IB
->getName().empty())
212 ibName
= ibProf
.IB
->getName().c_str();
219 float timeLock
= (float)CTime::ticksToSecond(ibProf
.AccumTime
)*1000 / max(_NumIBProfileFrame
,1U);
220 smprintf(tmp
, tmpSize
, "%16s%c: %2.3f ms", ibName
, ibProf
.Change
?'*':' ', timeLock
);
225 result
[_IBProfiles
.size()]= toString("Total: %2.3f", total
);
226 float volatileIBTimeLock
= (float)CTime::ticksToSecond(_VolatileIBLockTime
)*1000 / max(_NumIBProfileFrame
,1U);
227 result
[_IBProfiles
.size() + 1]= toString("Volatile Index Buffer lock time = %2.3f", volatileIBTimeLock
);
228 nlwarning("IB lock time = %2.3f", total
);
229 nlwarning("Volatile IB lock time = %2.3f", volatileIBTimeLock
);
233 contReset(_IBProfiles
);
236 // ***************************************************************************
238 void CDriverD3D::appendIBLockProfile(NLMISC::TTicks time
, CIndexBuffer
*ib
)
240 // must allocate a new place?
241 if(_CurIBLockCount
>=_IBProfiles
.size())
243 _IBProfiles
.resize(_IBProfiles
.size()+1);
244 _IBProfiles
[_CurIBLockCount
].IB
= ib
;
248 _IBProfiles
[_CurIBLockCount
].AccumTime
+= time
;
249 // if change of VBHard for this chrono place
250 if(_IBProfiles
[_CurIBLockCount
].IB
!= ib
)
253 _IBProfiles
[_CurIBLockCount
].IB
= ib
;
254 _IBProfiles
[_CurIBLockCount
].Change
= true;
261 // ***************************************************************************
262 void CDriverD3D::profileVBHardAllocation(std::vector
<std::string
> &result
)
265 result
.reserve(1000);
266 result
.push_back(toString("Memory Allocated: %4d Ko in AGP / %4d Ko in VRAM",
267 getAvailableVertexAGPMemory()/1000, getAvailableVertexVRAMMemory()/1000 ));
268 result
.push_back(toString("Num VBHard: %d", _VertexBufferHardSet
.size()));
270 uint totalMemUsed
= 0;
271 set
<CVBDrvInfosD3D
*>::iterator it
;
272 for(it
= _VertexBufferHardSet
.begin(); it
!=_VertexBufferHardSet
.end(); it
++)
274 CVBDrvInfosD3D
*vbHard
= *it
;
277 uint vSize
= vbHard
->VertexBufferPtr
->getVertexSize();
278 uint numVerts
= vbHard
->VertexBufferPtr
->getNumVertices();
279 totalMemUsed
+= vSize
*numVerts
;
282 result
.push_back(toString("Mem Used: %4d Ko", totalMemUsed
/1000) );
284 for(it
= _VertexBufferHardSet
.begin(); it
!=_VertexBufferHardSet
.end(); it
++)
286 CVBDrvInfosD3D
*vbHard
= *it
;
289 uint vSize
= vbHard
->VertexBufferPtr
->getVertexSize();
290 uint numVerts
= vbHard
->VertexBufferPtr
->getNumVertices();
291 result
.push_back(toString(" %16s: %4d ko (format: %d / numVerts: %d)",
292 vbHard
->VertexBufferPtr
->getName().c_str(), vSize
*numVerts
/1000, vSize
, numVerts
));
297 // ***************************************************************************
298 void CDriverD3D::profileIBAllocation(std::vector
<std::string
> &result
)
301 result
.reserve(1000);
302 result
.push_back(toString("Memory Allocated: %4d Ko in AGP / %4d Ko in VRAM",
303 getAvailableVertexAGPMemory()/1000, getAvailableVertexVRAMMemory()/1000 ));
304 result
.push_back(toString("Num Index buffers : %d", _IBDrvInfos
.size()));
306 uint totalMemUsed
= 0;
307 for(TIBDrvInfoPtrList::iterator it
= _IBDrvInfos
.begin(); it
!= _IBDrvInfos
.end(); ++it
)
309 CIBDrvInfosD3D
*ib
= NLMISC::safe_cast
<CIBDrvInfosD3D
*>(*it
);
312 uint numIndex
= ib
->IndexBufferPtr
->getNumIndexes();
313 totalMemUsed
+= sizeof(uint32
)*numIndex
;
316 result
.push_back(toString("Mem Used: %4d Ko", totalMemUsed
/1000) );
318 for(TIBDrvInfoPtrList::iterator it
= _IBDrvInfos
.begin(); it
!= _IBDrvInfos
.end(); ++it
)
320 CIBDrvInfosD3D
*ib
= NLMISC::safe_cast
<CIBDrvInfosD3D
*>(*it
);
323 uint numIndex
= ib
->IndexBufferPtr
->getNumIndexes();
324 result
.push_back(toString(" %16s: %4d ko ",
325 ib
->IndexBufferPtr
->getName().c_str(), sizeof(uint32
) * numIndex
));
330 // ***************************************************************************
332 void CDriverD3D::startBench (bool wantStandardDeviation
, bool quick
, bool reset
)
334 CHTimer::startBench (wantStandardDeviation
, quick
, reset
);
337 // ***************************************************************************
339 void CDriverD3D::endBench ()
341 CHTimer::endBench ();
344 // ***************************************************************************
346 void CDriverD3D::displayBench (class NLMISC::CLog
*log
)
349 CHTimer::displayHierarchicalByExecutionPathSorted(log
, CHTimer::TotalTime
, true, 48, 2);
350 CHTimer::displayHierarchical(log
, true, 48, 2);
351 CHTimer::displayByExecutionPath(log
, CHTimer::TotalTime
);
352 CHTimer::display(log
, CHTimer::TotalTime
);
353 CHTimer::display(log
, CHTimer::TotalTimeWithoutSons
);
356 // ***************************************************************************