1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "nel/misc/types_nl.h"
25 #include "nel/3d/driver.h"
26 #include "nel/3d/vertex_buffer.h"
27 #include "nel/misc/algo.h"
31 using namespace NLMISC
;
41 // ***************************************************************************
42 const uint32
IDriver::InterfaceVersion
= 0x70; // total video memory
44 // ***************************************************************************
45 IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )
48 _StaticMemoryToVRAM
=false;
52 // ***************************************************************************
55 // Must clean up everything before closing driver.
56 // Must doing this in release(), so assert here if not done...
58 CSynchronized
<TTexDrvInfoPtrMap
>::CAccessor
access(&_SyncTexDrvInfos
);
59 TTexDrvInfoPtrMap
&rTexDrvInfos
= access
.value();
60 nlassert(rTexDrvInfos
.empty());
63 nlassert(_TexDrvShares
.empty());
64 nlassert(_MatDrvInfos
.empty());
65 nlassert(_VBDrvInfos
.empty());
66 nlassert(_IBDrvInfos
.empty());
67 nlassert(_GPUPrgDrvInfos
.empty());
71 // ***************************************************************************
72 bool IDriver::release(void)
74 // Called by derived classes.
76 // DO THIS FIRST => to auto kill real textures (by smartptr).
77 // First, Because must not kill a pointer owned by a CSmartPtr.
78 // Release Textures drv.
79 ItTexDrvSharePtrList ittex
;
80 while( (ittex
= _TexDrvShares
.begin()) !=_TexDrvShares
.end() )
82 // NB: at CTextureDrvShare deletion, this->_TexDrvShares is updated (entry deleted);
87 // Release refptr of TextureDrvInfos. Should be all null (because of precedent pass).
89 CSynchronized
<TTexDrvInfoPtrMap
>::CAccessor
access(&_SyncTexDrvInfos
);
90 TTexDrvInfoPtrMap
&rTexDrvInfos
= access
.value();
92 // must be empty, because precedent pass should have deleted all.
93 nlassert(rTexDrvInfos
.empty());
96 // Release material drv.
97 ItMatDrvInfoPtrList itmat
;
98 while( (itmat
= _MatDrvInfos
.begin()) != _MatDrvInfos
.end() )
100 // NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted);
105 ItVBDrvInfoPtrList itvb
;
106 while( (itvb
= _VBDrvInfos
.begin()) != _VBDrvInfos
.end() )
108 // NB: at IVBDrvInfo deletion, this->_VBDrvInfos is updated (entry deleted);
113 ItIBDrvInfoPtrList itib
;
114 while( (itib
= _IBDrvInfos
.begin()) != _IBDrvInfos
.end() )
116 // NB: at IIBDrvInfo deletion, this->_IBDrvInfos is updated (entry deleted);
120 // Release GPUPrg drv.
121 ItGPUPrgDrvInfoPtrList itGPUPrg
;
122 while( (itGPUPrg
= _GPUPrgDrvInfos
.begin()) != _GPUPrgDrvInfos
.end() )
124 // NB: at IVertexProgramDrvInfos deletion, this->_GPUPrgDrvInfos is updated (entry deleted);
132 // ***************************************************************************
133 GfxMode::GfxMode(uint16 w
, uint16 h
, uint8 d
, bool windowed
, bool offscreen
, uint frequency
, sint8 aa
, const std::string
&displayDevice
)
135 DisplayDevice
= displayDevice
;
140 OffScreen
= offscreen
;
141 Frequency
= frequency
;
145 // ***************************************************************************
146 IDriver::TMessageBoxId
IDriver::systemMessageBox (const char* message
, const char* title
, IDriver::TMessageBoxType type
, IDriver::TMessageBoxIcon icon
)
148 static const char* icons
[iconCount
]=
160 static const char* messages
[typeCount
]=
163 "(O)k or (C)ancel ?",
165 "(A)bort (R)etry (I)gnore ?",
166 "(Y)es (N)o (C)ancel ?",
169 printf ("%s%s\n%s", icons
[icon
], title
, message
);
172 printf ("\n%s", messages
[type
]);
180 if ((type
==okType
)||(type
==okCancelType
))
185 if ((type
==yesNoCancelType
)||(type
==okCancelType
)||(type
==retryCancelType
))
190 if ((type
==yesNoCancelType
)||(type
==yesNoType
))
195 if ((type
==yesNoCancelType
)||(type
==yesNoType
))
200 if (type
==abortRetryIgnoreType
)
205 if (type
==abortRetryIgnoreType
)
210 if (type
==abortRetryIgnoreType
)
222 // ***************************************************************************
223 void IDriver::removeVBDrvInfoPtr(ItVBDrvInfoPtrList vbDrvInfoIt
)
225 _VBDrvInfos
.erase(vbDrvInfoIt
);
227 // ***************************************************************************
228 void IDriver::removeIBDrvInfoPtr(ItIBDrvInfoPtrList ibDrvInfoIt
)
230 _IBDrvInfos
.erase(ibDrvInfoIt
);
232 // ***************************************************************************
233 void IDriver::removeTextureDrvInfoPtr(ItTexDrvInfoPtrMap texDrvInfoIt
)
235 CSynchronized
<TTexDrvInfoPtrMap
>::CAccessor
access(&_SyncTexDrvInfos
);
236 TTexDrvInfoPtrMap
&rTexDrvInfos
= access
.value();
238 rTexDrvInfos
.erase(texDrvInfoIt
);
240 // ***************************************************************************
241 void IDriver::removeTextureDrvSharePtr(ItTexDrvSharePtrList texDrvShareIt
)
243 _TexDrvShares
.erase(texDrvShareIt
);
245 // ***************************************************************************
246 void IDriver::removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt
)
248 _MatDrvInfos
.erase(shaderIt
);
250 // ***************************************************************************
251 void IDriver::removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt
)
253 _GPUPrgDrvInfos
.erase(gpuPrgDrvInfoIt
);
256 // ***************************************************************************
257 bool IDriver::invalidateShareTexture (ITexture
&texture
)
259 // Create the shared Name.
261 getTextureShareName (texture
, name
);
263 // Look for the driver info for this share name
264 CSynchronized
<TTexDrvInfoPtrMap
>::CAccessor
access(&_SyncTexDrvInfos
);
265 TTexDrvInfoPtrMap
&rTexDrvInfos
= access
.value();
266 TTexDrvInfoPtrMap::iterator iteDrvInfo
= rTexDrvInfos
.find (name
);
267 if (iteDrvInfo
!= rTexDrvInfos
.end())
269 // Now parse all shared info
270 TTexDrvSharePtrList::iterator shareIte
= _TexDrvShares
.begin ();
271 while (shareIte
!= _TexDrvShares
.end ())
274 if ((*shareIte
)->DrvTexture
== iteDrvInfo
->second
)
277 TTexDrvSharePtrList::iterator toRemove
= shareIte
;
290 // ***************************************************************************
291 void IDriver::getTextureShareName (const ITexture
& tex
, string
&output
)
293 // Create the shared Name.
294 output
= toLowerAscii(tex
.getShareName());
296 // append format Id of the texture.
297 static char fmt
[256];
298 smprintf(fmt
, 256, "@Fmt:%d", (uint32
)tex
.getUploadFormat());
301 // append mipmap info
308 // ***************************************************************************
310 void IDriver::setStaticMemoryToVRAM (bool staticMemoryToVRAM
)
312 _StaticMemoryToVRAM
=staticMemoryToVRAM
;
315 // ***************************************************************************
316 class CTextureDebugInfo
322 bool operator<(const CTextureDebugInfo
&o
) const {return Line
<o
.Line
;}
325 class CTextureDebugKey
328 ITexture::TUploadFormat UpLoadFormat
;
329 ITexture::CTextureCategory
*Category
;
331 bool operator<(const CTextureDebugKey
&o
) const
333 const string
&s0
= Category
?Category
->Name
:_EmptyString
;
334 const string
&s1
= o
.Category
?o
.Category
->Name
:_EmptyString
;
336 return UpLoadFormat
<o
.UpLoadFormat
;
342 static std::string _EmptyString
;
344 std::string
CTextureDebugKey::_EmptyString
;
347 // ***************************************************************************
348 void IDriver::profileTextureUsage(std::vector
<std::string
> &result
)
350 std::set
<ITextureDrvInfos
*> texSet
;
353 // reserve result, sort by UploadFormat
354 map
<CTextureDebugKey
, vector
<CTextureDebugInfo
> > tempInfo
;
356 // Parse all the DrvShare list
358 ItTexDrvSharePtrList it
= _TexDrvShares
.begin();
359 for(;it
!=_TexDrvShares
.end();it
++)
361 // get TexDrvInfos and owner
362 ITextureDrvInfos
*gltext
= (ITextureDrvInfos
*)(ITextureDrvInfos
*)(*it
)->DrvTexture
;
363 ITexture
*text
= (*it
)->getOwnerTexture();
364 nlassert(gltext
&& text
);
366 // sort by upload format and texture category
367 CTextureDebugKey infoKey
;
368 infoKey
.UpLoadFormat
= text
->getUploadFormat();
369 nlassert(infoKey
.UpLoadFormat
<ITexture::UploadFormatCount
);
370 infoKey
.Category
= text
->getTextureCategory();
374 if(text
->supportSharing())
375 shareName
= toLowerAscii(text
->getShareName());
377 shareName
= "Not Shared";
379 // only if not already append to the set
380 if(texSet
.insert(gltext
).second
)
382 uint memCost
= gltext
->getTextureMemoryUsed();
384 string typeStr
= typeid(*text
).name();
385 strFindReplace(typeStr
, "class NL3D::", string());
386 tempInfo
[infoKey
].push_back(CTextureDebugInfo());
387 tempInfo
[infoKey
].back().Line
= toString("Type: %15s. ShareName: %s. Size: %d Ko",
391 tempInfo
[infoKey
].back().MemoryCost
= memCost
;
395 // For convenience, sort
396 map
<CTextureDebugKey
, vector
<CTextureDebugInfo
> >::iterator itCat
;
397 for(itCat
= tempInfo
.begin();itCat
!= tempInfo
.end();itCat
++)
398 sort(itCat
->second
.begin(), itCat
->second
.end());
400 // Store into result, appending Tag for each Mo reached. +10* is for extra lines and security
402 result
.reserve(texSet
.size() + 10*(tempInfo
.size()) + totalSize
/(1024*1024));
405 for(itCat
= tempInfo
.begin();itCat
!= tempInfo
.end();itCat
++)
407 const CTextureDebugKey
&infoKey
= itCat
->first
;
408 vector
<CTextureDebugInfo
> &infoVect
= itCat
->second
;
410 string strUploadFormat
;
411 switch(infoKey
.UpLoadFormat
)
413 case ITexture::Auto
: strUploadFormat
= ("Format: Auto"); break;
414 case ITexture::RGBA8888
: strUploadFormat
= ("Format: RGBA8888"); break;
415 case ITexture::RGBA4444
: strUploadFormat
= ("Format: RGBA4444"); break;
416 case ITexture::RGBA5551
: strUploadFormat
= ("Format: RGBA5551"); break;
417 case ITexture::RGB888
: strUploadFormat
= ("Format: RGB888"); break;
418 case ITexture::RGB565
: strUploadFormat
= ("Format: RGB565"); break;
419 case ITexture::DXTC1
: strUploadFormat
= ("Format: DXTC1"); break;
420 case ITexture::DXTC1Alpha
: strUploadFormat
= ("Format: DXTC1Alpha"); break;
421 case ITexture::DXTC3
: strUploadFormat
= ("Format: DXTC3"); break;
422 case ITexture::DXTC5
: strUploadFormat
= ("Format: DXTC5"); break;
423 case ITexture::Luminance
: strUploadFormat
= ("Format: Luminance"); break;
424 case ITexture::Alpha
: strUploadFormat
= ("Format: Alpha"); break;
425 case ITexture::AlphaLuminance
: strUploadFormat
= ("Format: AlphaLuminance"); break;
426 case ITexture::DsDt
: strUploadFormat
= ("Format: DsDt"); break;
427 default: strUploadFormat
= toString("Format??: %d", infoKey
.UpLoadFormat
); break;
431 result
.push_back(toString("**** %s. %s ****", infoKey
.Category
?infoKey
.Category
->Name
.c_str():"",
432 strUploadFormat
.c_str()) );
434 // display stats for this format
437 for(uint j
=0;j
<infoVect
.size();j
++)
439 result
.push_back(infoVect
[j
].Line
);
440 tagTotal
+= infoVect
[j
].MemoryCost
;
441 curTotal
+= infoVect
[j
].MemoryCost
;
442 if(tagTotal
>=1024*1024)
444 result
.push_back(toString("---- %.1f Mo", float(curTotal
)/(1024*1024)));
450 result
.push_back(toString("---- %.1f Mo", float(curTotal
)/(1024*1024)));
454 result
.push_back(toString("**** Total ****"));
455 result
.push_back(toString("Total: %d Ko", totalSize
/1024));
458 // ***************************************************************************